From f52538d401136c93e2c9099e3366055293ed7b26 Mon Sep 17 00:00:00 2001 From: Mark VanderVoord Date: Mon, 4 Jan 2016 19:30:38 -0500 Subject: [PATCH] - fix whitespace - tweak docs --- .gitattributes | 30 + docs/Unity Summary.odt | Bin 37198 -> 35836 bytes src/unity.c | 2648 ++++++++++++++++++++-------------------- 3 files changed, 1354 insertions(+), 1324 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ad95226 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,30 @@ +* text=auto + +# These files are text and should be normalized (convert crlf to lf) +*.rb text +*.test text +*.c text +*.cpp text +*.h text +*.txt text +*.yml text +*.s79 text +*.bat text +*.xcl text +*.inc text +*.info text +*.md text +makefile text +rakefile text + + +#These files are binary and should not be normalized +*.doc binary +*.odt binary +*.pdf binary +*.ewd binary +*.eww binary +*.dni binary +*.wsdt binary +*.dbgdt binary +*.mac binary diff --git a/docs/Unity Summary.odt b/docs/Unity Summary.odt index 2da4d3d368dc0159524f636b1eefd5df33439c0a..92f00105479aa0fd2622b4585343809fe7e51fd3 100644 GIT binary patch delta 29196 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 delta 30678 zcmaHyQ*h@^^ryp#HOa)8SQ95Rv29xu+x9oMjbE&ZZQHhO+sVGWH~-q&s(q@uK2?3u zSKW20PM_yJ1!6J}0!dy95()zh3>FM5-QGG5NfPjIRQeA!Egf|gWi3q=Ep07z4P$KsGfe{@ z6D@Tk9b*$?Z66bDBLl$D(AdJr+|bz4(%jI{!q~#f%*e{p%G|=)+Roh4(aqVy+|k<6 z!^zUg(aFil!^Pdj+1<;-$gvC1B1dN!h-_B{)@06AR;^>G$J7~HZn3kB_Sd- zAvz%?J~H7y64MjYlakUi(i8v7bWmDSMn*H$ZG`6(2G_xA%2+cYp?WvqujrdnVg^1{-?k8v2$S#@E^hW;;d~J4aV?#}11pkN-^_SInGr zPVCjrpSG=BbQgj8o67n+n&-NzW;$znI)R?C?yAAwwuPaVwVAG+vDWSBuD<^m7#$cM z92glN8R#1x9R4rH#>RSwX8J~F`zKaMCuT+`mM5ksd#4u$W;P~f=Evq%CzjXeCWfXb zXP0Nk=Kf=0bzymNVP$<~VQzVGd2M-NZEdZ8cDHZ+Vr*e|Wbt@nWq)k#44BxuURvMV z+}<4Az8>4TUf(^QKe$~yzF#}MUOTG|#D;q&toO&zHm42-=^LRdiAZS|r9$!qN}jq-S`@a^ou zXYTC6nak00W6h;#&f2yJJ%(VdfuJz5-MAt#oIDOwSpL1c{L~I=pjuBp4>lE*KZ4>? zHn>UuDDhI;RP&BxPPQkMLUhLH7o8AQe3(ro-5Rs?WF$usiO4@7SSX3ueAWwqnU1I9 zvavXtJAn_A*#02-?0w^&`f}eyu>$WxA4-PkRL?4o} zy`OBq9&Lfgy9E@c$kVB=JDG=Pxzny}z)iorl<0E~czL0zdfzqOa))ley$wMJL?5bD zP#4Zpwq6ctPEB8gV1&FetE`&egBGjOFBABT7iMYFjsm?9JO;KjP0#*^4uj z&w(!m72cKpkIj!KKvAKp>)Kx9ec4-!_mv6qriP*d?1gDxH<)<+$y}zBujW8P{&QID z>g#zj#^$9t{krNh<&gIyjxHN`{hho1rGT_F)CBv)8~NAEVC**-;f4Vi|I0Eany=gj zLxpQ8gO%UH{2MRCr8oB10lL=w+UK#@pB_dVV({mEB<%BKIdj5b6!6F^AHlZ07@u-t zXsytUtl-<5H<9Z!x)x9T!Q#rESR4PE9rJ%NrlzucM_=B65Ub7GZ(pyk zp%J?E4kV$MWA9R7Ih&Q+`HbvA(|WOjpD0!@`yXmo_IFP~bX{U3U%RAQpHFOjNN!`r z>KE>IT8& z*?!jE?WAInd9_Sa??8!PC^Y#JLwYda$SIXctgax5r(PpLp^LB24XuZH&33`Ws$(n78Og#ETD~?}M19UH( z$$4t(zG{b*hVDe>;NKTe%UE^tU5#TcvFn!pB*QvHp*(E)zg8(ztAeR3cIeX;{<}Q{ zDS}%<WH69Wk{$h7EiX_)qsh=3UyrKb|cfpKr(eqzQ0 z*5Aa`2AM4WP2hoh42L7tpb1|$K-3Xc{7jpN)-!MHREiXHW2P9SQ{u2Y+}D-Zj-4l` zB!5+EJi*?YvNLDmHV1$3Wsl35yb&~$#Gjhu40lEspdX!(Y4^s)8nXDda%?li5&)eWM{N}F6&18JHm1Vlyt^1erBG{ zHH{S45iMOmbh* z-#t+@=I;~10UpJ5*NytyG(?nGjup%r!&oPclo2hpkIjxH2D%F27ESUS@Z{M5wePG| z2S_WlHm4c(b^x`ZoeIl=2uo_|hsX$Zi=@KH2)w)l2RR3^U(l|BO>U*~D8FhQmZPn& zgN6ouieuQ12TI+9g?mNvq4fFvRew#A;z!=XcUcjy3cuY)zJR$ zpGfzt_Qjx*Z23AtB*E7$@WOP54)*y#*iK#6WKS3aX}1r!L4!VTG=JTVE`3%7oHn^% zyq3lAE!UN#ZZrhwJ-m$r>`xbG z53*m^mwF)CixBJQ{T8P3G@DQAc?&ZO7CjVVMtw5Ey|u?I?uiWF3A3NVh(G&{7+bep z^ca{?E}C$qgS)2gW3qmZ38gL=30KR@C0xz^O}@Cl+$d`7V4QsjEu{O)>gUrOe$~fl zH6BeQZ`oAQHl|l1RpALd$o9`WMZ#af#wAY~9GB9eXc-f1>|0sqgW0EK{wf&m4V$hq z0CDr7W%Bk&#c%&0*9YxG#kIvs4+NztGGb;Sh7=gm6Qk+7q3+ezK~Q^;%aax2(oC2< z`!dkd7DG~_riMn`wiA()5})|Tz~pjJ$BpW45BAOZA{4(1M56ySF+q05eWT$u8X4(z< zE)t7u3%F7G2cPDH6-S)={YZxtqMyg`cYpEw$h%To?#$izwl zLMhx=K6$=lfZs&~>wQ5yCik-<4!EUgSR_hMW#_!CBs8*<3Hbu*-)=Ic{d~g5 z!$TWermq#EM4EtVuqlh&wp#)aYT2ux#Lw?{7Rg2}KhxjTD&$ z!kf`MN1PEFvUyIl*i3Y+J)VZt4k(Z?_u&dPq*V@%~_qm=NyWl=9AzZTi_=0cGZX>p7Px_Sp;B zWXPy;^2-zEPJr&XZl>d&Ig7vi_rO_w}E8{1c4hM;%2S^!^P zW3|5fhWN@3TMI6GTZ)xe2uZ0gHmKL#*YU^K-cUQcCd*x#?Btk>Yt-~*&G$ZR9-WR* zPdBLPJ)gx>C4y3PFRSG#&Jz7=>>=I@x=#Wj5}Ti~^#fd1=rC#EJrU?CtE1mgONWu$ zh`A)m#k0y1hDiP_o(1azfpw}7HVhNUO0-7l9&F=(kJ*NoZBtKGeGCJj-PnryjN60S z{Nh>`p?Q*GP2B4DAv33} zBv1jQZ}^>@a23G{dPjEUD?ttQtSBZ9}Y#*dmqjWBB{FlMW&4uW{7O1!OrEf8vmC(nxe7;<}O_)&ioK zml)roSgq%TD6q5#^9N%D4Q$D!;3G5 z#s&{3tD#4QI=?!>l89s9x_a-c#lAP0U^0tFe&oBwg*mPl`tfxqj2*eJshFALU&yWv zFD_PB&hH0>6!Q-;l?=IMjEj)o3NcT|xhXL&Po4fa>f*M5d$q?kQ^BYk5@OIY{n_QZ z4b_0dWmIk6zYob4&0k%*s-ro|s=n#URA3?{)Tau+=FjwU^NJSkG~_1(TGN%}B@f7p zO&l@gl`&IFB|pOz)m0Hn4s*38g}}G&psF7)szuHQaT|ZaIBt$^Q`2mS9Ci zY7(nWG59+G8VN9k+VY9h`o45)2(lo(QR|2$ZHYE);wI<>bXK)P- zlfXmzM!A_3#^`~=OD5C0-I|05*)N7+#b2jm;%^6^&%N%kiTMcn^;8t!|AFu$3Z)!t z?G7b0!i;A5?HhTZvy zaT0k2#7V<0sV|y<&X&#@lWM2)!}ctY>Xc;R^d~MO&?gQSy2-Ln@in}6?UTJU^9^A% z-R=*NcHSG=8IMFEL9@PK+^3yPjKTDG>^c3TMG=qeo#O@l+gCUOsTCQ%847QoMkBJp zm%swt23LT!(6G-X#{+$Ao^@Ltw0+Tt>@Yj*{Y0)#YMpbn!w@5L>eK_f29=D*G+Ni1 zh?p00G=vS;n8D^a8HF1fS#PAT9cED;>Iym#g|UOKOk@Y*Zy&ekC*-<}PQ+H_aeEBR zCRaciyZ!{bW{eEl1y3f0c6%iGk$1co$yQ^QF%eH|t{{$T(oXim&Fut{tIBU}HX^3A z>@MXe&`!*dvm&qs_r-Mo^X4|louRQj>=@YJ#Xc^9_um@4cq(-l&rlx)K zm%x**SvIn|v@C+&PgbQ3)sLA3uEz%;MKgVa)A2`cR90LjPj~lycW4I!6UWXA%6HKY z^~tiLBJJsNB>|N!Nv6M0={pcrC6m#LlQh0e#maXo%1NFI4Z7hbL`kzhpy$g<7Zjxa z!5!2peiG?h4VGMzV;eWHR3sQ0lSchJs=`pN(rgJcO2nMM(vk>Q)#@Y&Dk=K~$WSw2 zE~sKulrH)fS^PM76)YM2V^&=~IO43Bm+07KFS&aG!Hr2kjf$2O;X7xhEIooo#ziMf zsWg5}{+kw_$%CxP&VvG$(Z?MAxMSAs{#xBdAuV(?E|S)l{Bt}3Lgp!QxX0{w;idj>p zr0f?=?|Yg6uzW2zypQtBrH(mP^o=lXc0qJ&7XpWGybYO6E~^WV=N&mqz?^|_)aG|1 z$!(sR3iX5GF=Jn1w>uJaJ8tRsbZ-CMiSa)1!`%BhdfU1gvC>ssw(i)J*8O+T+$wiq z9Mt4v+a<){%ZrFuE4xTc5^R;VfOrli`zMp%;cIsJ9BB<0UKSZY34aBJSFS>L^`!pR zN+Lo(73(Du%~%pZ2EhMkB>t4-F)Ooow#gj9z>?h3`IaCLJk zGRt=km5Z*B&0v8yT1FRx@+z($DB@Sl)~)Xqhe1ax`F$T2J)q=$4f6)qEOOWu5uC1) z=?sq=Pjr*zO0V-JxYg1?-g_;*wBYnTokC-vKQ%t=iB{XX8pvk?{ua$0;KDvpt1QTZ z3bWeJpDZ?q@eXR;IxEvt9pF@S!iuvIKKPTA8~oZ=$KC%ZCCt_x@73@AZO&^{F8#+B z2csFp?Eg}vWHAXezF46ymFYY##+3p5LzSXRRjo5paPD6FGVQs*M!}5P2vmCH&xT!(Pa`y3*kAM+Y|5-nl1kuz%+3bLmAM}T5~Hp)O#Ud1LcX%9!-N}qJsC0S${H?3@4 zFwE+2G*;(3w^|{hYqnl#r^6v!Wm*d1A)zgsqBer88>fJlAq~W z42D4%ehncO(vjlqABXayMOu%!Tg?{G{UnVZ(1}WMqG8&Mb4=}VTRz5eAVG`VOH0gI9TG3aJf*Fj7U{gKgzi14bS;a9}H(YHp@VK6_$W+drsMGLyw z_v$)|bN43s4nN;x zgOE34P1t4^MV{!O@yyd}8b&Y%FM0vghQ4f&gAQJuW?k zLqn0-++J5wl0oqymB_dyXx)-SLfLa&P&Qpgy1!rf;@zK2R%Br1*#JI~434Y-Yd;it z6=Eh#8T}sXP~&CIsu`-9OlBS}B|9$l>*3dsQtfZ(f|q$N!{&vvae7xN3u<8MyYm9V zcm93uP)ud?LgsOQ110{?CyDd#6n$$qbnY4xiihE3a}cL z@#+e&D>D83&I456`Gm(I)anlOxdt2{P8EF~4o^>v#tg6j3;U$yNe{FV%w97Z%QdC0 zy&(Kmkl?VRlf-_5??)`Wp>O|);toq0jmj>I{RDmo`%UB9fG4sjsQr$ke{OB@u7F4r`c*_u%RY$j>*xUma*G`=8ldxo(y_i>YFGx$z_L^;=R^KqhA+X$kz~wPM2>{2~OT8ddJ*ydhoV% z?--hldKNrf5paH@ohS{eAv6MDJ$~E#5w=oB%^qDwrQdb=ZD@G2h-P_U!?}?4SZvko z=MuH(GTqss!?LWOnc-Glm2w<3@tQe*Y@Em?NwmDa_?!JS=%V`Jyuju(tqNP{(I>B= zCA^7+VJC*~Q0SD73sTg>ZAlNhwr@iiLB4)T0_WZRci?YN1t$z#@Gy z5YDQg4#N5i8r$D>poRWkQl5@?>kif#uN_-ZnDl&lBIaf<(W)Rdl6Tn{JlS^ zWIbr*oNSnOe5#Y3q4*5o@;JmI7m+S7XyJ$rl?#ZkO@A(-W$A2Voq_p+&> zpBPo(_`!g|Fg^+6lIQ4fIXaK0a*$>zq-EZ)VvJs;-d-0c@oZ^j z#1bh_vFlK9DKR4?zDIMr6b+?AK(F3}A1YC`603R8#o}ZaFXtZsClo+PTi9?Q*uwlA zWoc^5CXK$mJC{(C+I`sUMRMOfI?67Adn+*_fyx@xABu6y!~)`u`%Pvd#Pg>yJvHSe zmI&JLd&VyZ(D(#QKAPA;SOSP$16SceM0DGvFJ`G2ohc2yhy_jcX8`(~pY|Bd*!qlu zozZr+;o!i~CkQRk)^6S>O3_nhGPriZnwu%SLIiy8JQ z=D8iR5fki301R((q7y;0mb#Zh3<($?8N10JZTGp z%F#ts2eZol>v}p*UE4`wp!eFx9l&-)q!B%n#6u{-U4=EH-baAs@sEVW|79OE3yR-n z{W9`ch&cvehvIZmiG(0VD@^3BX{VS3B2VRvy=t7o^fC)q7^k3h%`jV(hFtQ9y2<;r zBd=gq;0Cd_U-&in>K$5lyg--Z#jWStCS37s@KNeQ zaPxspd73)dpHe2Sf<}tmPfMYT2LVR!JLOv3!Z5&u!|RUmFT0}K-->4z%)siNMToil zt~@sN+|F~Gh#z&0OEun&JlEh*wItS=MLVtFb&Uns=+pTf9`|Tq52vMcREVvJ=R*BL zte?NzGn}wzkn5KZh4n%TCs>;iveY+Mf-deW+EExMS%Q~vf2qZSPu-6bYQQ7b> ziWXW{4-eT9Z9=NDv0vuY^qbqP4zDux`>SF_xGHZNzv}$%k}z?hjx-;4xq=j|n(;%a zg4feG5>bL_&A;yEa+7EY!=HU+!UJz8gI*Ice#TUrvjX=++Emz1&jsN`p)t}3`h!4y z?YOBZt&-9XyPvd_#&0s{9U7&nw*jJY38HzNgq6PWzp4Tw5F@MM%tSIlv&19Cp_E_{ z?&#>Omv~nggG--y7nc&G`At=1edgQE!sjA8taHj%SdnPZh_}2J*yhk3kaQs-p{jdT zY1xskD2Vr2m*CGX*-6~eOvgs*Pf-At1e=KvRjqZc8LR$VdCpS)k3Q<{(+`ifI-Yk! z6^>MC%)!nE6m^^{HMw+e5rd^uR9V!wU}l;t3{jVAG!hek?fM>z7}KGtCxkptCW&ed zwLhab#0t*d?^b3YLR-r$YGkQiYT3}69I8S&Xm?lX)Dcuay=`_0X2DphB@UozIHc6i zP=J0o(+4inQ9le-*j&{6dgrb){WpxD0gK_PfXMMCkbf9oF z$|T#bFZ-T1zy6uSv2+q% zO~-ORms0VV8joXn`1I~C{^2lV$5KRCPdOGly9AUCOq*;rng-X981C?}CMbkBpAfs< z-{v|tS3VJibHfb#upBUUv@u3|39@KN;~A$enqZ`bFWLxyNd-58X?X(8KvyBldK%xw zUfdAVnugQ)8!)@Rw%+>Ptd7$oQ{FNB^68&jsL!~68WQz4OJ|O?FwDd0xP&REM_%Va z!KT$|%*?uhIf{CSgFi8?8Tr+>jR2=u|JGc|mm*ml(KE!vVl#+AV@Acmj4oS2G0L z2&4CBa=2Biqd1&#W#r_R(n`qikEhvmaNNZk%*)gF!Tcw41R+kZzmDFykYXsYp)=-O z^y3^N*aEy&)sQ&dXD%9zTvMLvyxJWH8#*B{Kvx9_|MqV!@{75>UMJT z@T`oawRODdMRK$DOJ=v3G`nW9=~0KhdyN2`+*v1Yy7+|Od0v6|%}7cAczJx8)QkH; z5c4pV(&)KY3)w_+@u?hln!aLP+IuaiZ*UhuQ4F5UF&@+!i=K?s0!?I04^?zn)IFfX z!clS!fd}ZO>BeK=phZix{4&FnpiHVIJK6^&YA1eARHmB%XHH3gIB6;_v8udaD)?c( zl@J|+b$Xm8+dc&a3K3h4L~U3w{OyjsKpbkpag0w)R9SJ?z08uCi2~huZ1eN_sxPYN zT!^!2#wLxOAI#7*1MV!(Ds=RVKCO9bc6s}e@Gn5}icGkEv%j}>#?gV!Yjk_>Lda9_ z`45t_+IP>Iasm~Ct2HwAq-C0Z+M42#=%uX*Z?&#KVlcvU!=>rbluF^K9rB#08v<(R zA8smHDq5p#$zR=03*?q}bopOBZg43}$BGwFxZz-r!fvVfq9cZ2yCc4AZzzc70?*&~ zUF(1jracsT=!rnAKea>A=tCNoPc??6fHWA}1*yRD2wG?qL6Ho;p>&A!kJc1tlww{z zv@VAb(de>vAE`i-QytWs$XD#D1lWZa>PqKH^d%*!)hxv$le`~9Nn2#`VJFj4>48yZ zP=&`*SwwDNyuRB<`n$~|hek|lV^TLo#OMGow@pZtV8Rj@A}x3 zVsKFEGaB$<6Z6^9(!6s+2pSpEG5ugX+NNpol_1Pd2qqDfS&Wr_nOJNZf7Fl} z-S|KGMu|cTU*rztFU$38_KJvcHpJVM>$>oyN5j=+l79=bf- zgiK$u4bkwIgEsiR)o0OlPr!%u_XazitoY1uzcd}Q>>WwyM9?yIbz&*3;{N+}AXh0Y z@uyd!1h{CpjCAZSiCDB)_K!g9`n?bw#c(o;J}WX@!$NTo>6GL5?9hrp5e3wuVaY)( zv;pewq5Qk{BVE*+CELEsqfP&pErr>lqSp<7{h4}V@NLn0iMgm+R-n#cBPVRW;Rdto zMiqCpYC*^sol(}qd)xBoI4K)O)y0RO{eIV+^0)e?Iel^_0$4FH>n6MkiUn_XBT6V& z8(Rn6*WgWLZ_zsh&zi*#&nPaJ3?vk6XOwe_Qh9U(Cxb?MJ-cezjcD6!ON-3~Wiu`_ zH>)o9qW~V6;9pKTGJxe?M{v(O%|%rx`bG?~?48epuBCM@#k>LJaI|bleugk{=jKXG z>Vwyhc|H7#Ayi24HibIy4t99E(e+bqE9M2X7(Dx3%C0Y4e4b@^}HUdEMfp9GkF%^2rS_flDZN$c=uib$l#_w=lujy|?QKR}8t3eJ?nT1L~JhkP<9 zWH!giJ2TzM+7dd7hrR;LgVeoikYy=9+Y%4X&xrKfNcq3Ys`^e&4`d@!TgbsV;NQn@ zL&_V-Ksh{tUbP2$l=|;N=JUbF+(M~wR#i~)+dVaK@Jmnke1dkcRthRsYojM7KC$Mf zWY6V6hdv;|jlDMoe|WcxPV2%m%tGT-blVY#U@ixfOKZ0tPfN4t?|WgvS5A(Xbf{ zm+KICWUjzj130VS?n9_C{;-`M5t{iSrAl)oW(ulTK_b@#V;A7W7C^G!E|f~Q#jG~GNzi#59b6h=8N6{B>=t`W%P z^gg2 zx9%|QdDh~}w23#|zVJbchFE#Ex2ykMYl47W-j(pi1wV%gBx@_z>h_(!JAvh=qnsOt`zihAIQ@r| zyAe`5E8^;?M|pe)0ije&T8d2Ww8>Ma(MQj>AdKt-R3-s9qO|bV51z1u8Bpl^Ae@UW z8lbS1CxfV<@)v7;P9PtpaL=nHI;$oxfPz1D$YMS=v)AHZ5EN?_jwo&DReTfOJ0&a& zOF%8%15Dr0Wc;jwHO+!4ZErG?;&+Vza>@U_?XVk0e2Q&+kV<#tk zm&WL%YhKt&WPO)5%j0UcwkCg`)B1s|HXu-gmIwQ{%M#;viYVm}*rPDYNa4T&pwRi( zU;jG?(r&EuU*GJP!q9!QuKnv6cA$>%kQc3({+p>`6k$Vy<&BD^m2)7STVYz1dk*=M zy$J64m;K25khhu%8y#?&Z zM|&s()4n6zk(L9G1jC}|P3`gfi)gpZZ>s17OYR3UT=ao9T2Aje7&ogjmeWh5r`wT> zGU#|>G7!IdkoxgrIzCq$_%f!K*G^i8w|Xfi&2v*YYyFVlmdx86=FXdTm$`!coHEUX z?qhcj<|x9KW9rd_E&^ZxVf43=pFj*U(Pv!pBEy%G87d`Wz?(vmW6u64iF(4OgnqT( zF<0hbUvzVL(5 z$_>geu5zem#F0!ejV|>pvzL9&>AN}0c86iHVK8gK#EP-l>X+S(**Qya1&~Qq9gHXw zTc`IZDBkpIp8#e!{_HLA0xuR_kjq1+EiGl^Lp-5IZ}TFsz3}2fM+=2rg+lRFo2@m( z%3qebSozY(zn9`)(~2c5L>ZibFC^Oz3|@w${`|nL1Pn{- z#J@m~uq84ypTr??ps12T3+wO}JDrJjAG*lKW5<`}hk;znfdq>KV?a^*k8VX$$4p&{ z3X&>r)-;Ar8w$@1+UeKM{j@9^lM)j{auGTEHtv(V zfS$uh@3V{oR51lCEdXsM)f?tEU5%h<+cXZTn^v zKgE>Q!6NeYJZ$HAAj`E7cfyM;5ChLc{YoPw_82XH^pok^>IKwHdpMzyZqY-g$5LrN zx*l>n^e1HGG3Sx>iG({MEVApuz4y`Jy(jOPKusXlsRV(nB7o{we^zRu6vxc=(K$3C zjlye@4qg8SW=snDHd%NPSNf%7VrIs+WeC%ZQ#dZ#^g%pqE_LiX6QM`tk3(nxdu5Dh zzID)UxFUWiLe5EZ)VDAmNOsVFJGb^Mt{PumM7VE+X5>ID0(Mi zh1s7h44o)h6By;e%aBEoaF;zSweK<)_=#04;MGVL!E_?ROEWbA-=ZxzDkB~XN;F}) zE!%!rO3_V~3!xWZcmYujQ5H-ziygJMY^_8N#;eW9Ix^fLD2jdg`ninD1*?>c_fe9lSxmIF(OAva zJ}5Om4xD*fk=r)=&LF*3)bxoMT1HCmusx`sl)7kkt(?%xY>-FRI+~*#iH9(e9rt?s z%x?GfQR$r|y$GPfzR<}QCD`|LArcR#F6|hK6L4YYNfyMcOhDV$6{hEyVZOXYOpqo+ z93j9p#x<&h;*}4=^68g0G`gMC0NiQUTJNlafV4jE@=$jOf8us~xhdniUF@=pEIB!E zJf?O~GghDucy_koblZip9h}n0z#Q2|t4a)Rvk!#j1Gv~&Dxh}2ct|AA0)5d`6!Vkd zc)h|E*B=>Xh6y5vF9PYlF)|(IlTY1@=|Ksr1Bg5fbCKSvLw_?J7cXXt@Dt-#W81_4 zsPph;maAJT7V-y)pU-$uDmlwDVP|;soH{D0e7kE=Dp#F8{%fL7wKVxfZ~m-n81PtP zJlu*sFe7&rNES9{O-t{vBW8n%zZs2Jmnk|r*iRFZYJqigwy}{+)CHxOCXAfp%O}Q5 zYUi!A^xj%&r+fbhCAS7DU$lQyCZ;e0bzm0BiW0G23h@}Rsbi8OPRlUiX<_?$zo9kL z_njQ*U*zw~s*1XyTOJ|AI~f`1WCG4HrkgrbrRXURH#h8VvZa01 z`gUl0uCLNTJ_);My1jVUWNFx9x7Sqa3QpQoK#S#2Mcrb&r1)e1JCE%?zeX4xKu0AN z?%k3H-GudbN$^;`I`Qu)&6p&;tId5LTYTAmy-b+ns&;K*nzp_D`$K7C2N_S}a;jdk zl4EirQMn6fDX|bVY;U0nZDy+>Z%W}FpoyNOH6=V5g`0%Ppsgj6{Xap@6F_~2iV7hK^1*3AqaWc5J} zjF>Fa$lDY)IfksV&y-Uaas%2n{@8))5b01t^j$Z*RNY=~KdyRosDuge@P$8g{p-E$ z5xedE&yRIlBC$hY?ESUD?HBPJ7ov7p_sD{3=zC90l&eO50J0OJ?ewRF&h+=*vP(Us6T% zlkcipDyCZ`!Y6bgoA`FfcCNOc%q)L==vYVo2%iPv4W1MoDod#@maimbq#2WI>Lkod zYa+00{vKg$WA7q9E;!9?AdkpBZL=O=@D8%yE!OK%28#_s!uFj4_%aI3Q2bjf)WM*! zk?%^^==7@5o!CLdjV-*`Chhot``ise4F@$IAu$@yy zPSO#6*06%jXr*q`taXVjBJdMke++6pFEruZ zwhkb6M(urQt=$uoosPvPb~1s~_l;zlbk&cx*iw>~SnH@N*Tv1JYv*4zbX1FMM-|;$ zl~+)~+rjn$jfY}YTa4i%cs$nxAcN7N$g%Z>pSP#xKDA#6isc0IuC-rSd*83ZkcQIE~nB1TT5t#4@W)HZJm=oAC_b6b!vfADezSmZqhK&x6&Z5S)@C z(c*}bSE}jgF)!&4w=z+CfV)!~KcOT?hU)X`m8$^|(eFoIe=!VD7KxzBRQJNBen0w) zxPMiuR5G4Ba63CkiekXY67_PTsDMOL^l8PJC-VIhx+o^%3fy>f)6K$I z{$FPyzL(F~6Z?MAZhAXAS9Md-sPxRbz5nLGf3BOuY(Scn!U@fpHclXNoZF3!59qkm z&mm_4&$aCvpVfVJoYOp^T+iVwArssRn;=%-d;++@BHZ9u~VX9 z&)SB)3S;C$k|f<(h-5&EY%MKjpHj~YRo!(2@W*Nu`Gz0s^rNW)9l#Aze^8+!XN89& zGT|?5Ql`m8iiku*)Qigt5?_87=Kj(Rck>o(NlO!N6795Y+Yq^Eis~5eVp$O<;%+X8 z!ewng5cP^zy<(9a=+L-d?Is1Y8Btr=24UHvP95B9#yQJ}St8t~uuUV$37yKx&1pUZ zl{K$4fM-*CzkkE2Z0xo4n5&TJ=Y9ds3v&m{#4=KKokon;$jYN7id9C&(hP-n*JPbk z&=G5lKtjseYFz$e=EnpBfoL3#cGp-aQ7BT7v`pDF)4DLxA9XRjD4ET3S)&Xjhs)<3 z4aiyJpioFy7yhsOI$e{`MSJNr8R3-XNKw*@|kqxIEu+ z*YbSH8W2RBK5+NtAz1DN%KGwt<@8$6hdimX)2A& zqVIIWxm7;U8|7zJ~CN8;K;V9$2k^6=>*7b@UN#kgjgoJU>g-8Tg&a2YM zRh1%}=CA3rEDozYw89GtxB37Rr)m~Cjh&PAJH5#bm^5mZYCQ{OYIrB7FAERfDp}k2 zJ=h-}McOMDlE^A-r@DevG(A!JTaPi>m=m3u+Pv@UeUzH@bUP`W)7}TqXOY@GLLecz zwbD>z`-v3vR`lG`BV+=hvM4yr$qly)sJr^%%ErYeBwGM3PCn0y=VoS{7h(SqXc~o7w?Yk37LqsZR4~@3rT<_ z=ud)leT&5%qMN3ypgvI05^)M+`qUFr0SVh}{j;A*lX9K4EI($4ST`m;-H*k{ZbbkA zbDilK(v{z}6jA z{z>i=8q$P>JyN=6b7g zOk`&y{0nU%5EZJI*a>^c>bTjn8TiU{I+)&L{X!4 z!l1ZBfo@`}qH(FTaiK}#sJ4X0g7KVTEfFf&3uzw`pJ6cj4j&&!{m;jm9von2QjlbMl8gh5q{xEX7f(TE$vcYT*- z4RTAiXB7=sF<)zdt3vT!+wE|~dObs5!KJ7^#FuN1^S|ili?W8_$T1|jUd|ZdoyuZi zo)}0*W|{;me+g&Q--XHZbDSJsmu)hK-wLb@-y5e@>&IfG3D+t*)Dg#62W`PiT<&C* z8*e(`PcvbwHwi=g2?KU{ulv^2EIY_>@U5+pLi#3lCQUE^*CyPMkPxkVR>*$%tggMUA)_QFM3Ke<|{4y`C%n6Js9NnCYW%<3iy|OWSPBqnpnr`J>j*?aeoH zVj}i8ZblPahw9cIMP@Su5*8Od-6X!+`KH{7FH;B*y6AF7qdo*q%x{-m-l)QvX5#8l^FFWBO!_2Xi+lc)+u2)=y((W`WH<$V<6QxfjQe*5`-->OjJOS8%WhV-mi%-y+>s4S7@!hIHCh_;MC&(&bhH`7nR z^y2Ckx7FoK_nuWzME8~d@o7Xef=9Y_kFIj&B-H!N>n9>@9%fSawF?H8VSA zW@cu`%#@g!6EoW}teJVu%*@OXJ7#8PwquSNp3k}W{B^$Xe^qa)G}81)BTY}&j&@pV z*&~wq@W7?`RBf*=udQ1E9&H!`o|dr316~7w+BkE>S+H{pJ2_eM#rEroqAbX?0(IMG z;!+UXwFYgSt(~*q$-FKb2!D|{o%)?o+?w0P^3=R}Pd@f>y#g(OpPtu=ys#v58;Gf= zx3-&p)5uH-Wj?L{6o0l(DS_<)9k5f)KlFWIdMrl^FQ!IE9|53 zQTD|gDSshCuYlFz;X~v0hsM4Sg(3ea3;}*<6!MB2s9q3Kv_BN-&%=)po$T<1Ng)pP znX9LN&!skImWuCCqB28TC(ZKVCq59hOMIvAu;GA~**0bqszTV0uwRfHL&g~Ld~JL2 zqL$Vl_R6;A!=NS`kw3)C>HcQB*+6dB;7^gUd0Ykyu(w&-Zb{NHdbJw7%Xb`5ul^4W)os$ z>h>i`U%PzuQp*}L=Ac4JyV>iV117f$STb>)O5xgPTPzqT!gH0?-_!-0)Wz;nr|#C3 zn=m}$?^YZY2MP+`8Y;iWJ`X~Q{`ol?4V#d-Y$v^vLTh_!vm9m|w(f@A zJHu`~A+;QPQ6O@U8#nJoQ8e=No(44OUwxIj?U}G_-rKB3TP)bAH>bIA1f0!=>Z0>; z-WZ}5ve}!oh!@oB-@QqdoIOa`$8StwRquk4HTKjQxvP3MJMb37b%Q!0{#}_w?8a8o zGS;Frz`Y1cwmBHz9nRc59o{`c=y~2RT>E3nR;7B$hHq_mK5i0-TkWL2g)#!c?}6e< zRMUz$r0(M>g$vi%mEY}oo7gQSl|%tF&@c?6_hUjh-M7z%@ALV7 z_OGTKg}CMdK8;0VS%Z+Rr8}Q(wLVGvL^nCUiIQBH<_xbY28d80clRH%+~U1A9KS<& z2N%H{MorW`27l|WQUw~y#u}uzk=|`NN`~bYQs%nL=gA>du)^`~% z#!y_avT3s$uh_{kFl=Fd_8Z5&{4(4Y&IiD6L&j8q&ZZ4hYc>BA750o%9Qv$&pE;!P z^}y$Hw3h^DUa<7Vw!}NiIwbUp`aNlcrCNaXG1l+eixalLgs4zvE2OR}%+_)OmLI|Y zi=SK2KCmdJMg(Z#Y-|6hKXt0#1mf29VmkCM)x?*td)G8fe(6#~tX_g@5T<<3%(}Mw z9Y(*~IW%rI>l>o-rr8`zAs~y^yQwF4d{&s$c1SyG{{RxB~pXg(h9WBk|st_VWJv+R0t5 zbieUd)5#0yI4(kLzh-4J&nhKK5(B+9-Hwri=|wHr2w}R&PBb5FL3XIm7?L!;%-=@-{{u+Q&-*XezyoZZag>7JYu5-M79&oXWWAy zJc0oF;lS{`rE=cO<{J}+_K8U!)Q7xkuHRt917H&heZ9_5O1w+n_y;Mk-GS%!*49~Q1cI9%J}U^B9m6?J4uMD`4!zy`DBFh$f=NlH#4 zNJz+>XQqDPM)cqvwowye&y`Slp%FoU@xz1+_EE@$ec+RLJD2f;J%12+NMnaAop%zc z-T*#kjY+D`6)>;ysKNpb0MQPxN7Gl#%DuXhB0#?)-pLod2tx9G1uiUN^ z0pNc!x-gCW$r}nG;@6>`o=Ky`cQ=NYE_(KUkU7ZHQUx<6kxYMf$0@jk>1DL(z6}N>NtTmuv zFzpLYj{H~X*D0kR6EW2Wiy8GGxi@t!e~jd7zynhiZ#4v(s}+rbVNeGISU%3$y~c!6 zmn>L#ImMrs5}t2G8BAcwBt`MCE$mRXWLXerF1=HK!U~VzL<7Gl{OE5tRA5xBBI*g% z-IM5J0Zj8@=NJjPrr8qd`44Lt>tv3VM~H@8G-gVl0<^_f9}BcDuyz z*j2l3*Kctuw@c{Bb;$as`(omVgt$LkawN_SOBFTumYU6(&y?g?jFAw+ol1ngJDwfpo!bY2t_80S>TN3v(DxDMeXCn*e62*8`6N6o7=Ya z^VWptwig_CIAS+!>q3FH{WJksZ4iN%}L|Syw0`Ha(ex}UV^o)R)8Ef>x2|m-n7shRO076~%I*;lrknM9xf9}5m3{IIL zlq0|T6~L(R>Xx+C757LO{vidz_UPh)VBxkHFwo}x{M!Y2NwllzsUv^#edE6jR}CyH zX)ehuq=u6ks)vsIENAmhgk%(=$Dk=I*?j!XZ+~u3WvIwq5Xb8?e@)%8M;w3f9&BWg zQ6Mx5tfiq$*e3;tfuRQdUU6;e6m;vbGS7UvoRv~ycgT6+0PZ7zHYym9C%Tfv42T-{ zeS31)okS-2))-YD+0ntw{WGx#JW37}#0GyHPHQ}7%7Mse!4M=X+JgQZtC`q$pn zP#onP_*2~D(4Hu9VUa0*A8s@3^f>hfK1s+c66j>cJHIyy#8^8S2He)jI+=)i(y}}r zq%cwAjIFkKRg~N6_aYZy%L;&xa;_Qn3uKBIE)tg-%oB`MO7K*6{8N@x+l#1{_hUpM z*0+~P3fOXzpCoJzdU)yCrvW5i7Xt9HfFG+@rFGy`!nVg_$tJjZP8h_QUD5xNmE&Hk zsp%-GlWOOKP)?tw_*@r)7=eJ-%((n8txYUCRO#?*R`Tdo{@2PLkfjdJ#)N%H*|f>A zn~-Edl7_sb+n?5y&v_PS5)L3+gYE&o24>?xo~ezFaEbnKwS)2C-drbH0fsS4{$1WY zsV)L534~bKGVh8R{`$>)&XH%LCBgQ3}lxiG(=)5*elHn;EyY;spQ*sQ?IM!iTc4u&2%!Zvb3CLp|FnzX> z`1PIN>PD=^qk_hJMn3Z&@;M6Oj#qh}GJYOb8Xz{0^2H+)1u`Qm#{s<8_3<`V#yrEF z3RO_By;&uVBdw4z5}%5VFQUBcGIR$Xi%n$Mc8um=+I`Zy~~|_&5mjd zYYFUS0#*G<^Ml5b84Bj)+?Q5UA&HD$bMYpT!^=1&<5Vh%}VF*kVg@Wj)Cfn@XQkE zjNnnimJm}@_YgN+EII&+)I#ePowpSXJSMpS+cKq$lA|<*J`cqTJT_eCNvc7;#EF}Q z-n?+lm&B-_l3&SzfJSxVz0-G!y)C)Eu%BtVD0n5;2htHnVni{P6P$*s1Y5yIQ_0#8 zxJ=4iW{E@zuzT48nA$Rgv^M8Jm*>7;SzE&I+=G=Zt4%mZ{PxRVT>Tg~;C8Y|jCF5{ zJ9HUZAs5OC_`tL=CFjZIP5S^k4r5S*P*m5-lD#C}03qNs%qcVyWf8`Arrjgd+8!W4 zmri63_~mNwGxAs3V0aGOxHtwVQ(AzgklDVc%orb07FByTl{*#@mduHtf z@?Ka}xg|iGSTyQ^oD``O_`XbTkssi2KJ6R|$OLW4ytUJBiGbUHsp`+l2Tp@t|HgX7 zlva!NQhWCF5LEZ#(qFYIHjm+|vaN&e$B_aBjHtycK^mZTFJKb+#m8d7x&^21n{;IF z@*oc5TH=(#5k?uA#FxW3r2{i&3BTih_6z1{qooII%DrE|7_G}SFyu&v(Gv|F=K*#M z;Rp;uFuuZv$3d!!KpIo!{=bly7fR{uKiD5BCC z646u$V4m>^#Z1TB&1C@>abH3tcmfrk!_rWpuSe0bFRC}<-M8lg)TlH*qxx{c-waYn`n3(t1Awox;f-g zWG7l(XBc8G#Kh%=0(7IGJuHoiHhy;k6lfAr1 z*9^8^LgarsTYj1jDleZMJxxCajw%(Oa!H#F^1o#pB;9X_W2;=xvywp3i=Sh8lk48! z?Y)$dHR(*X?rV;PExS2a4H*FwV$x}uJn=CSi)!6zmkf2It>4k7&NkxNrX&k~U(CqK z&Ai7;7}PK$1Q85FC$iS%k*9vYIa44P0e>n5Uq@;{aV!@OeAf!-l)RY$9w}9lPv`9m z|6!Qkg1iB1&cZQVmkd0BXnJQw_iN%-^5KXb;88MJIA}HLcT7go7l%gPq}sQ$S$%4t z#X5aRcXc(l=2=}GIs4TsTx6jS{(yiA<|z3?t0LII%&2-y3p`&9+&OEvu(lUv#z{a^ z*%x~)`Yw~WFx_& zM73cp%7!Fudr*{(c~0%)ys!AwvnS#;OyFj025NYoA&hmwmXJeeJ!BeDG?Z|iFQ@%B z$$V2KHB9^tG?jQZ<6!RAmJ?iGk#A7Q9xA+J+I4B}BYldqRw}3wXdc+d}>2+^R+UTkcY zPge2!?(Fd6`19;NF%wYho&555Haw_`_mSPd?qJJotfU_K%hH4ON4B*7wWmSvlZ$7z z)rtl7;;G5(D;uUcF!;MQzwj>EtM06)+tcBK+JxP+&vT$TEHEL(R0~ZNv&DkcuC)zZ zFSwLr0nKE=nBb(r1VZS%ISxmXak`ff?dmWfiJ!xxuQP_05S`j*7p zs}4qD*-ALEtT3T=@AwqGZO8ZZf{iu*zs%R>3 zb2^TpO^U$rVALV{u^i72k#_4lUnCIGZYUzVw_}=?olO>OYMy4jq5O7iKMq5L$bBDq zZvKJv`6AkqnNi+CbkxGvN5w>Z57T4+`&iM5L!lsIpfUwEH=xe71;#fS{9wYyiir`6 zQn4Oyr-oWn(1i$Y<1i0-<5iP)N5HBsBaonTp_rV7EJjvz^!E6$G#%t`^mO&-6Y11= zam3ARd3klFViS4Y_rT8(F0Z)ph4wAEEtT`wSB%gSEEE3VjFe*5jmpSx`}6a|F~z5b zu=LZ3Km!OU2L8<#nhn-9zJ+?qX8&DAy6snCmLP8Ig4|bA8HhWw-=jFx$x{0BaZb=B zfS5imGdUOoY64OxcBnp3$7)OnHJ@Kggz?w4W_CB;vFS{%)I}9(>Q;BL2_7S3kvO_O zMd$F*8=9qW2CzmI?AX55(}nD96MVcbrQkE>z|E9SJ@49}$)+jSW<`>GxMooyTtpWq zM-Pu{xvO(<Q=XPjD@S%d!)y!E7ASdh7FVj zc6upPzv>CS;>m}_KmBsJY#<;S$^*qp=CplQNeDw;HR*Q`zunmdkvvqmBSVeyh!3bx z@2MxHe^-fWrITNL;%lw?YWF;>+5x;zoN2FpcR}x{egAxQjJf&EC-Y<1rR>G`>)x$f zG5q3!Nx{Kl9R`M`-=X8NUQgv3s67x{aDgt6`=ZwTo6tMCT=+udM=-6Y$MQL$(~v@S|H(b)@{xCak(TKRQR-*v2o z%*&tTGV2|fSXI=I19n&Im4MN9%&yK}p4;`itD{6jn^kA-&^+SY!r6M={OvTY@B+9L zc?VuuEd0hrKkMCC5czahtL12>0bPi7FwGe6mnc$~TUXx!&GvCZJLoXZPy!pP-ZQYUb1JRARP z(Mn~IJZSN7yW4FK;wdohDp7n83TA#${^k%N!)-=pf;y~vXoz>*00J`;I0IAj$`^2a z+djm`qU|LUxv+~D!$KotS+y7=`SQd>PZYdL)?#CPh;eg_2Ruz->7fs`@ySTlh>Q>jmOlh5r*Pj;4!!f$HE!s@}NN#K4$?35G-#YX>D zGeU8Y0S=6za7MBl+(_{PpNu{0HazFgEJLP;v@e64kdkw`$=h#KUN-fQiMr8spbOKr z&}u6id*BP|R-DyfPoz@Ff&q2K%q&>Z8|dtIzu&oKmhXK0U*9&gNfpAo{}LmP4K-e8 zWIqy>rg(z4A6B8VF9tE9iFUjeU@qVGJ@XM(s~=dUX+-%E^#%cA7^sa2W9QN0DE=j7 z%1cNqNbh8b9>G95XwZT;U~pCtK}=KT#|Z($iY4()t;+^21_rs5$uB&k+j`TEyJ)dK z&4S@HEWhE?5Nbqp7NwYu6N`VRAlm$Wx|$sPJ0-1JiR5Inh+e3;k8SoSxigx zc8N05$6|AQze4i9yt<<_Xl`QH^Dl%0??}E&G1LdT3GtRmxRjT+C<62-^XoifT`kIj z*Mq+Fo#&Mqxyj7e=%jvcd2rU}nvW}T<^(rvmQ}c1pm-D?U_(5nm&KDG3}+?N&Nx2& zwB4QXj0%crBuOSQdBRrWOyOws_4nJ}S@3R_M`4bn9aI2XM0 zx!be~fv+%o)KzbCp{#}zkp7`_F{1HWJY)=1iCH z5=Tl5wNYmpRwLp>jpc_bU7mVYYRU(H-d=1a_%3Jl%aa-ZRTml}nV^=ZF!S@!T% zuJ8PzYdYa34vw$1^t4~m%V$Y|K%~HkQYjZ>A6;q75M!0;{$FGF4M(=Mw+QBam!R0&%!>WFP!HjBE+)()3E!jsNJB~t1uRz7LEv=fjvWllz52rhl*`Rp*RL37 zO^@jhkh#k_>i_C(HvSYMKuv#0=aPS^7%cQ8s}Ggbl51>E(=!bZrC zss+VZpsXXZu^K%iPl^3}Ff3va(v-#|W}pj0Ny6-hksIC~Rl?>TS~=B3sh7O!VEL^< zE`vhEEWI!8a%Pp8jeF{LvJNg(w>2>RQf|D!VAF+@+_eUB)$a|7)r`hIwV_QdfKY>8 z#oTi&IYa!^FbF6vtv!HN1qRY;?CxCWh7vF^%Ll=+3|=btXA!16SS0MGe8F&YDfQv? z%`EJ1C^uIdf8-boFHpJsN{yBEqDcwfth>d`rXjG528+C2G55#D4;CNelWuDd;=Cd! z6L*q|iboce{lf0jeSyhTc(l;%MM!}$x}IucRK8IOYdPA`yy2CYHgGn*bKh+IFghh; zdm1~?y<<&o`Jr16F*N_2%!I5*D)7@Tdf8fZ)+wQSGAV{{C;(jfQ#e*8YI;dU%aqud zQrhX+U<68X(A+DPZlA6-HZkNUbSbb4%7@pkTd%V3N`=d`cau_4Ey^DY+cdT&%E1P! zm{aYUt-Gw&siZB)hXL2LrOBGH5{D`&DIKjmMpK5rsU8Py4jJg~;DT)~5?9Mo}&5pD16GvAr>5PGS&6RD!D`MFE3^d}MHC$U=+RwuQM zy4rk%e!Q$9fEs*~a4Sx3&VVE+fCevT!BpZ~GIETuo}PTNunBNDGEbRK1F?raJl`kU zfOf}Fya|56JMn%-0RsanrZDlYO|$zJG7>CXysRoeX9nz3J~cGUNv0YV;HW|(Vz7tL z2XVbRSrw6(Sy(r_i%C-w-}0KKB1bW3hEhFzzR)Ntll+siY zVtGbB4ZGg*3iq1B!5IaA6{Ix_5j4AFr4(7S#LaE_eYcj_Yku7?kAzI6FUZLnK50Ck zzIFG7H*9`t1#5xTH_=no&oq!-BveNQ>z!98RHRq2q1XT}H+mxS5pN@mCCl?~Sv!JR z=&&Ww_`TGEDLm)MT0>60K5WYQ6mRc0e}t{*X=eHiYB5(~GAMWGxgLGf6T-^CYVa2R z3}2N@PseZaa%Fs7zmoKXtV!gh1sy@r=y*-3+!w#Uu6Zl-tmNYCSZQpcrSXyrlItGf zQ4`vwR=wvn2*)&2-M>s*-~MXo`nn{jL&6xH2EhO zJk(>(TAUyYFrY*^`iG=YA+{bX zhm1Thtv|f&@fsjUpDF%b+~f>(Fi9lqxly#mY_X8!;lRG)R_>-&!G-)~j*Ez}j7xAI z9}WkYFeOPte6p1{iuag~qN%%ToGaBS@UT7 z?K4O7Ang@N$Dzf=ja4b61Z~~6bp6rYRtng5A!?4U9+^|-1H8;yh5>|k{D1~ZpQp>y z_U|3TB}}HUs}KjN!F4z@`D6bry##g2;89$lp}g{U{WLu4?Db7fj|R)PtqQGfFH+cZ|J^X*N#>F26Lh!B)w zSbYxXH4;^Cos)0A z7R$sO?TZ7UAuo1$OZ$Acispo^M>f zzZn_&c81B8Ws9ok2X+e`D}p!B&d$OvKq)dzMbf;6Zpa#k8C-Um9`lX{I7Z3otvQ?_ zwJR$B1b5fD~!C4rQXi&I;5&s($OV(XA9hbf>}uAx92a6LBX>JN)ofe~Lb2c2AZP#mPeKORLJ zf)>FCV2_yUTs`X`v5F=F79q}$1)Arh@`&7;#-KNmh$I*S&2gG?X5||*h zf+X2$$BpSQG))I@Y*eXt&7ne>UOMmmiBrgeFsMIT6my-A%!4Bp$eGL}c{*S_Ot`fS z1HL(I2)OBTGy$^ILcA>5>{lUPEyQ<-&OSlIK@rKV>3acjK{lwS*7@*=5i{Bi$)vW1 zGt&$?B-!WJe-w1>Vcy`Es2m0eF)g>_y*T+75R2+3HX^v#F!eB?C-FJ+h? zM{@WRFZs@K4nyj+XRqJM4@#jY%oBm)CzGA9iLg(;rlrf1C z6f6S+A3i<1gca#!`ey7pjUNl#cATwDTkGSKTjV7%tQ+SDk}OvkZ7mMN8r?dH3Mq=J z)y?0d1s|Ry6LC`H?stB0%@2DZ?OXBlFM=7jWb1hjLQ?d=WBvfkDxOVu_?V_zd2N-y zdLtiYjKtpqQWJ+II_w{VGDyF6K;lnhFTT=c_Og*F`Gn_aMgSZFG}_DKy`AYSYAktfJydEr6wM=$ccwR%_tl* zk`%$J@KOWZsNG4_dfyu5gtcF;kt9hfkC-JQ&xkMxxUy6LQ932T;GCe5h||sK_RXkgeoP6 zd1jg4i}M_P+m}W;&<&=}mnq2&XJ6|Czu$`}>GzUq85fnI_-Zk`@lkj|Su*k9K}(%$ zbx%SBkipaUs;Z9sK%F|F2Wk(ISeG4FdVp_to$#aRPUGyd6Kw*QpY)#?LVj-75}0%1 zP*GFxNgfd>^=zr+%tjL%+L9R?-=wEGEd7BUrD0``uYTs$^`)!NFtfkMGp#*0(W>ZS z_;iJ$wquBzL>zkcvE@lS(Z@Z`1s?H(;uJVDfu*PAL%v5%vl5V8n=FRo9Y{?2%>0|d zKPFR}8qkzH(jEOog=19PY9O+ST3?4cp;ke2p18$ET^+v1#KWj9BZ=JZD?0Kl!zl(VrJQyw&g;C*ie!Q*X6rZGy##)D+Tbi_M=66yQ&U zyW8fL_tMyQ;|*A|Jcy84rGS;>N?NMA-Iv<*m*Yg}qA%`-epL`BX@}}{z*Dxk5Eu>e zWh{c>@D(?ogtC{*QWgueC9FYf0>iY#RRJ%{Ei=3Qu_Zl$PJywTFM2!%QrNDXY- zX=bcqyDx;IyVgi4Qjy{01)>J{yWE(nf!()T_BijG(}0l1C6e}y*Qk%GR3B7$P={uAsEV^0b)b-?`VT)n4*0NCF|o8uAO-`s^>#6Uf_6&_UY zO@p{TPg(SMWgeLyh_sB1a0Ddd%Uy7u0LHojsd$K&XTss0BEu%kd}?&ym~?)s=Y@3F zb3^E_Wqg`(m5pR3VcmoYkzgDL-d5&LM4dxoxoo1hw!W*B5ak#ad6U=!-2m3xP@(+A z!YYgA3%SyG7t^%UHdEH4HXz(-imz_BI`G|jop-c~0W!J%d1fx9K%Z&y@CM~(1m+9q z+N@HYzPd1B3PPQaXwY)ldO=9iLaidT8A&*qw3p?(8yboaniD?YQ^9S ziLkC+8#uq%U^e$Q!2!KpUR2M=J5RL>eV4uW9X)hfTZC4s4#>fZtFbH=l>GQ-Upo_x zPisC&BsVV?^7EKQ0T16a7&oMZ>xqdvT`b5eq(61dj7J2A6gIkbZ@Jx z&A?G|J?P`%uy?fj0|5RRLPc&mh&(vU=}K_utiAJRpYgkRm~rC)P4z;Yqw4_)tavS&jy%sMFO{<$RjGa6gL(` zausO?1?LLuFYFf%A+@cqI&?DVshEf}!r)4he!2sw)(oKW-%B7X~SWgrcW?! z{VC8!iPWr(>#u=frCJDI$Hq{zXWb#0sJgK5toZ?+qbwp69c&0AF3PZ0#e|%dnbV+-xoIrPE~4K#hz#Rt>CjLQ2)4Fsy22vAh=t? znGUe1s!igw2ic0OIM5NXnsAAzF5g;fBto-y-T6(t`WH-07P=<9TT8D&yc>6MC2 z%tK^w*|=i>W$yVA@p_^<A5LN%tplfWT8=5PpydlpfxA=?b|dusk(1H!gH@D0T z=-;V;XudJ!ETlEl!-3Nvb4^fQgO182s@{ur$k8A+E2$YbMt5%Cu6GMk z6l@-63}%@Gz1Ow4Ql)mKK5^+1ZBH9Y0`Ch_aEeh5_QH9%<<}i05%vursxr>>?*wol zu8N+{V{ny~EgM?VPi)u5eSDf(5ee-H1E7$h-KE4kN>QIZ7Kep-YyP~6kUu+D(5HhpCSxU-8+(~+P1L=#f;tbM_cLRT zN1lb)y&katPAub#sKtc_07_{7Ni6&4)$`;}4a7+w^yL(D{YuaIy-+^yjLc-yXpM!7 zjjG_i>!5U)CIXFq;uZN`*C2I${kipSqo+Z&yfcP7_rh;STl(wo*TKGflADWgW`1u0 zS>!L48=0cZTZl;>6J^?biFZC0nDZ5hj9&LKFzY!TJ`!22q=elcs|JqUu+ zEC-&;bgi?$J#Rnm^U4{_EVYy96Nn(@%e z#m75_RIModE{s>N-7HXM6rSf_9}g-a@h`an}7obxGvB(L!=^R@8s%DuaNnmUEF2(Z9p z<*#7xgI1OiH0hoO$HYd{sjQk;hrad1)83eZy36XuY*mYSjf%FFdmAM>>I$Iop zQLi$I7Rh#BEmV^GHn2D|<`3d2$}Kg`G@Z2ROw-2-H-4L|*Yvht4dSmcL_=}JzyJ;aoI(DtF;uS`6!*7l0=f)l|6i3=L98J>uzwX>{VTN*ua;;d5FhX+1*AB9@~0>;1ntbcZhf}jR&W`=(R z{yT!D{_U+H{KNYItJF`OEl! zxBpKjJQq-Q=>LmJ*#)#^M}YJ{6oZgIEDCn{um}Sr6!z)=r-u07IssiSAVquf|C;{K zjsL~*@jU+CsQ-)qgPvVL%HjWUGyhVf>I%{brTM!b{yGeI{kSnKPeuNB-6Ne*i?-B1QlJ diff --git a/src/unity.c b/src/unity.c index cfdcd76..b5c788e 100644 --- a/src/unity.c +++ b/src/unity.c @@ -1,1324 +1,1324 @@ -/* ========================================================================= - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -============================================================================ */ - -#include "unity.h" -#include - -#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; longjmp(Unity.AbortFrame, 1); } -#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; longjmp(Unity.AbortFrame, 1); } -/// return prematurely if we are already in failure or ignore state -#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} } - -struct _Unity Unity; - -const char UnityStrOk[] = "OK"; -const char UnityStrPass[] = "PASS"; -const char UnityStrFail[] = "FAIL"; -const char UnityStrIgnore[] = "IGNORE"; -const char UnityStrNull[] = "NULL"; -const char UnityStrSpacer[] = ". "; -const char UnityStrExpected[] = " Expected "; -const char UnityStrWas[] = " Was "; -const char UnityStrTo[] = " To "; -const char UnityStrElement[] = " Element "; -const char UnityStrByte[] = " Byte "; -const char UnityStrMemory[] = " Memory Mismatch."; -const char UnityStrDelta[] = " Values Not Within Delta "; -const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; -const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; -const char UnityStrNullPointerForActual[] = " Actual pointer was NULL"; -const char UnityStrNot[] = "Not "; -const char UnityStrInf[] = "Infinity"; -const char UnityStrNegInf[] = "Negative Infinity"; -const char UnityStrNaN[] = "NaN"; -const char UnityStrDet[] = "Determinate"; -const char UnityStrErrFloat[] = "Unity Floating Point Disabled"; -const char UnityStrErrDouble[] = "Unity Double Precision Disabled"; -const char UnityStrErr64[] = "Unity 64-bit Support Disabled"; -const char UnityStrBreaker[] = "-----------------------"; -const char UnityStrResultsTests[] = " Tests "; -const char UnityStrResultsFailures[] = " Failures "; -const char UnityStrResultsIgnored[] = " Ignored "; -const char UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; -const char UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; - -#ifdef UNITY_FLOAT_NEEDS_ZERO -// Dividing by these constants produces +/- infinity. -// The rationale is given in UnityAssertFloatIsInf's body. -static const _UF f_zero = 0.0f; -#endif - -// compiler-generic print formatting masks -const _U_UINT UnitySizeMask[] = -{ - 255u, // 0xFF - 65535u, // 0xFFFF - 65535u, - 4294967295u, // 0xFFFFFFFF - 4294967295u, - 4294967295u, - 4294967295u -#ifdef UNITY_SUPPORT_64 - ,0xFFFFFFFFFFFFFFFF -#endif -}; - -void UnityPrintFail(void); -void UnityPrintOk(void); - -//----------------------------------------------- -// Pretty Printers & Test Result Output Handlers -//----------------------------------------------- - -void UnityPrint(const char* string) -{ - const char* pch = string; - - if (pch != NULL) - { - while (*pch) - { - // printable characters plus CR & LF are printed - if ((*pch <= 126) && (*pch >= 32)) - { - UNITY_OUTPUT_CHAR(*pch); - } - //write escaped carriage returns - else if (*pch == 13) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('r'); - } - //write escaped line feeds - else if (*pch == 10) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('n'); - } - // unprintable characters are shown as codes - else - { - UNITY_OUTPUT_CHAR('\\'); - UnityPrintNumberHex((_U_UINT)*pch, 2); - } - pch++; - } - } -} - -void UnityPrintLen(const char* string, const _UU32 length); -void UnityPrintLen(const char* string, const _UU32 length) -{ - const char* pch = string; - - if (pch != NULL) - { - while (*pch && (_UU32)(pch - string) < length) - { - // printable characters plus CR & LF are printed - if ((*pch <= 126) && (*pch >= 32)) - { - UNITY_OUTPUT_CHAR(*pch); - } - //write escaped carriage returns - else if (*pch == 13) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('r'); - } - //write escaped line feeds - else if (*pch == 10) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('n'); - } - // unprintable characters are shown as codes - else - { - UNITY_OUTPUT_CHAR('\\'); - UnityPrintNumberHex((_U_UINT)*pch, 2); - } - pch++; - } - } -} - -//----------------------------------------------- -void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style) -{ - if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) - { - UnityPrintNumber(number); - } - else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) - { - UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] ); - } - else - { - UnityPrintNumberHex((_U_UINT)number, (char)((style & 0x000F) << 1)); - } -} - -//----------------------------------------------- -/// basically do an itoa using as little ram as possible -void UnityPrintNumber(const _U_SINT number_to_print) -{ - _U_UINT divisor = 1; - _U_UINT next_divisor; - _U_UINT number; - - if (number_to_print < 0) - { - //A negative number, including MIN negative - UNITY_OUTPUT_CHAR('-'); - number = (_U_UINT)(-number_to_print); - } - else - { - //Non-negative number - number = (_U_UINT)number_to_print; - } - - // figure out initial divisor - while (number / divisor > 9) - { - next_divisor = divisor * 10; - if (next_divisor > divisor) - divisor = next_divisor; - else - break; - } - - // now mod and print, then divide divisor - do - { - UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); - divisor /= 10; - } - while (divisor > 0); -} - -//----------------------------------------------- -/// basically do an itoa using as little ram as possible -void UnityPrintNumberUnsigned(const _U_UINT number) -{ - _U_UINT divisor = 1; - _U_UINT next_divisor; - - // figure out initial divisor - while (number / divisor > 9) - { - next_divisor = divisor * 10; - if (next_divisor > divisor) - divisor = next_divisor; - else - break; - } - - // now mod and print, then divide divisor - do - { - UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); - divisor /= 10; - } - while (divisor > 0); -} - -//----------------------------------------------- -void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print) -{ - _U_UINT nibble; - char nibbles = nibbles_to_print; - UNITY_OUTPUT_CHAR('0'); - UNITY_OUTPUT_CHAR('x'); - - while (nibbles > 0) - { - nibble = (number >> (--nibbles << 2)) & 0x0000000F; - if (nibble <= 9) - { - UNITY_OUTPUT_CHAR((char)('0' + nibble)); - } - else - { - UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); - } - } -} - -//----------------------------------------------- -void UnityPrintMask(const _U_UINT mask, const _U_UINT number) -{ - _U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1); - _US32 i; - - for (i = 0; i < UNITY_INT_WIDTH; i++) - { - if (current_bit & mask) - { - if (current_bit & number) - { - UNITY_OUTPUT_CHAR('1'); - } - else - { - UNITY_OUTPUT_CHAR('0'); - } - } - else - { - UNITY_OUTPUT_CHAR('X'); - } - current_bit = current_bit >> 1; - } -} - -//----------------------------------------------- -#ifdef UNITY_FLOAT_VERBOSE -#include -void UnityPrintFloat(_UF number) -{ - char TempBuffer[32]; - sprintf(TempBuffer, "%.6f", number); - UnityPrint(TempBuffer); -} -#endif - -//----------------------------------------------- - -void UnityPrintFail(void); -void UnityPrintFail(void) -{ - UnityPrint(UnityStrFail); -} - -void UnityPrintOk(void); -void UnityPrintOk(void) -{ - UnityPrint(UnityStrOk); -} - -//----------------------------------------------- -static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line); -static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) -{ -#ifndef UNITY_FIXTURES - UnityPrint(file); - UNITY_OUTPUT_CHAR(':'); - UnityPrintNumber((_U_SINT)line); - UNITY_OUTPUT_CHAR(':'); - UnityPrint(Unity.CurrentTestName); - UNITY_OUTPUT_CHAR(':'); -#else - UNITY_UNUSED(file); - UNITY_UNUSED(line); -#endif -} - -//----------------------------------------------- -static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line); -static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) -{ -#ifndef UNITY_FIXTURES - UnityTestResultsBegin(Unity.TestFile, line); -#else - UNITY_UNUSED(line); -#endif - UnityPrint(UnityStrFail); - UNITY_OUTPUT_CHAR(':'); -} - -//----------------------------------------------- -void UnityConcludeTest(void) -{ - if (Unity.CurrentTestIgnored) - { - Unity.TestIgnores++; - } - else if (!Unity.CurrentTestFailed) - { - UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); - UnityPrint(UnityStrPass); - } - else - { - Unity.TestFailures++; - } - - Unity.CurrentTestFailed = 0; - Unity.CurrentTestIgnored = 0; - UNITY_PRINT_EOL(); -} - -//----------------------------------------------- -static void UnityAddMsgIfSpecified(const char* msg); -static void UnityAddMsgIfSpecified(const char* msg) -{ - if (msg) - { - UnityPrint(UnityStrSpacer); -#ifndef UNITY_EXCLUDE_DETAILS - if (Unity.CurrentDetail1) - { - UnityPrint(UnityStrDetail1Name); - UnityPrint(Unity.CurrentDetail1); - if (Unity.CurrentDetail2) - { - UnityPrint(UnityStrDetail2Name); - UnityPrint(Unity.CurrentDetail2); - } - UnityPrint(UnityStrSpacer); - } -#endif - UnityPrint(msg); - } -} - -//----------------------------------------------- -static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual); -static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) -{ - UnityPrint(UnityStrExpected); - if (expected != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrint(expected); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } - UnityPrint(UnityStrWas); - if (actual != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrint(actual); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } -} - -//----------------------------------------------- -static void UnityPrintExpectedAndActualStringsLen(const char* expected, const char* actual, const _UU32 length) -{ - UnityPrint(UnityStrExpected); - if (expected != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrintLen(expected, length); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } - UnityPrint(UnityStrWas); - if (actual != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrintLen(actual, length); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } -} - - - -//----------------------------------------------- -// Assertion & Control Helpers -//----------------------------------------------- - -static int UnityCheckArraysForNull(UNITY_INTERNAL_PTR expected, UNITY_INTERNAL_PTR actual, const UNITY_LINE_TYPE lineNumber, const char* msg) -{ - //return true if they are both NULL - if ((expected == NULL) && (actual == NULL)) - return 1; - - //throw error if just expected is NULL - if (expected == NULL) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrNullPointerForExpected); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - //throw error if just actual is NULL - if (actual == NULL) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrNullPointerForActual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - //return false if neither is NULL - return 0; -} - -//----------------------------------------------- -// Assertion Functions -//----------------------------------------------- - -void UnityAssertBits(const _U_SINT mask, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_SKIP_EXECUTION; - - if ((mask & expected) != (mask & actual)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - UnityPrintMask((_U_UINT)mask, (_U_UINT)expected); - UnityPrint(UnityStrWas); - UnityPrintMask((_U_UINT)mask, (_U_UINT)actual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertEqualNumber(const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - UNITY_SKIP_EXECUTION; - - if (expected != actual) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(expected, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(actual, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - _UU32 elements = num_elements; - UNITY_INTERNAL_PTR ptr_exp = (UNITY_INTERNAL_PTR)expected; - UNITY_INTERNAL_PTR ptr_act = (UNITY_INTERNAL_PTR)actual; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - // If style is UNITY_DISPLAY_STYLE_INT, we'll fall into the default case rather than the INT16 or INT32 (etc) case - // as UNITY_DISPLAY_STYLE_INT includes a flag for UNITY_DISPLAY_RANGE_AUTO, which the width-specific - // variants do not. Therefore remove this flag. - switch(style & (UNITY_DISPLAY_STYLE_T)(~UNITY_DISPLAY_RANGE_AUTO)) - { - case UNITY_DISPLAY_STYLE_HEX8: - case UNITY_DISPLAY_STYLE_INT8: - case UNITY_DISPLAY_STYLE_UINT8: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); - } - break; - case UNITY_DISPLAY_STYLE_HEX16: - case UNITY_DISPLAY_STYLE_INT16: - case UNITY_DISPLAY_STYLE_UINT16: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 2); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 2); - } - break; -#ifdef UNITY_SUPPORT_64 - case UNITY_DISPLAY_STYLE_HEX64: - case UNITY_DISPLAY_STYLE_INT64: - case UNITY_DISPLAY_STYLE_UINT64: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 8); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 8); - } - break; -#endif - default: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 4); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 4); - } - break; - } -} - -//----------------------------------------------- -#ifndef UNITY_EXCLUDE_FLOAT -void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, - UNITY_PTR_ATTRIBUTE const _UF* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 elements = num_elements; - UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected; - UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual; - _UF diff, tol; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - diff = *ptr_expected - *ptr_actual; - if (diff < 0.0f) - diff = 0.0f - diff; - tol = UNITY_FLOAT_PRECISION * *ptr_expected; - if (tol < 0.0f) - tol = 0.0f - tol; - - //This first part of this condition will catch any NaN or Infinite values - if ((diff * 0.0f != 0.0f) || (diff > tol)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat(*ptr_expected); - UnityPrint(UnityStrWas); - UnityPrintFloat(*ptr_actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_expected++; - ptr_actual++; - } -} - -//----------------------------------------------- -void UnityAssertFloatsWithin(const _UF delta, - const _UF expected, - const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UF diff = actual - expected; - _UF pos_delta = delta; - - UNITY_SKIP_EXECUTION; - - if (diff < 0.0f) - { - diff = 0.0f - diff; - } - if (pos_delta < 0.0f) - { - pos_delta = 0.0f - pos_delta; - } - - //This first part of this condition will catch any NaN or Infinite values - if ((diff * 0.0f != 0.0f) || (pos_delta < diff)) - { - UnityTestResultsFailBegin(lineNumber); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat(expected); - UnityPrint(UnityStrWas); - UnityPrintFloat(actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertFloatSpecial(const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style) -{ - const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; - _U_SINT should_be_trait = ((_U_SINT)style & 1); - _U_SINT is_trait = !should_be_trait; - _U_SINT trait_index = style >> 1; - - UNITY_SKIP_EXECUTION; - - switch(style) - { - //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly - //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise - case UNITY_FLOAT_IS_INF: - case UNITY_FLOAT_IS_NOT_INF: - is_trait = isinf(actual) & ispos(actual); - break; - case UNITY_FLOAT_IS_NEG_INF: - case UNITY_FLOAT_IS_NOT_NEG_INF: - is_trait = isinf(actual) & isneg(actual); - break; - - //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. - case UNITY_FLOAT_IS_NAN: - case UNITY_FLOAT_IS_NOT_NAN: - is_trait = isnan(actual); - break; - - //A determinate number is non infinite and not NaN. (therefore the opposite of the two above) - case UNITY_FLOAT_IS_DET: - case UNITY_FLOAT_IS_NOT_DET: - if (isinf(actual) | isnan(actual)) - is_trait = 0; - else - is_trait = 1; - break; - - default: - break; - } - - if (is_trait != should_be_trait) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - if (!should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); - UnityPrint(UnityStrWas); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrintFloat(actual); -#else - if (should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -#endif //not UNITY_EXCLUDE_FLOAT - -//----------------------------------------------- -#ifndef UNITY_EXCLUDE_DOUBLE -void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, - UNITY_PTR_ATTRIBUTE const _UD* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 elements = num_elements; - UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected; - UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual; - _UD diff, tol; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - diff = *ptr_expected - *ptr_actual; - if (diff < 0.0) - diff = 0.0 - diff; - tol = UNITY_DOUBLE_PRECISION * *ptr_expected; - if (tol < 0.0) - tol = 0.0 - tol; - - //This first part of this condition will catch any NaN or Infinite values - if ((diff * 0.0 != 0.0) || (diff > tol)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat((float)(*ptr_expected)); - UnityPrint(UnityStrWas); - UnityPrintFloat((float)(*ptr_actual)); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_expected++; - ptr_actual++; - } -} - -//----------------------------------------------- -void UnityAssertDoublesWithin(const _UD delta, - const _UD expected, - const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UD diff = actual - expected; - _UD pos_delta = delta; - - UNITY_SKIP_EXECUTION; - - if (diff < 0.0) - { - diff = 0.0 - diff; - } - if (pos_delta < 0.0) - { - pos_delta = 0.0 - pos_delta; - } - - //This first part of this condition will catch any NaN or Infinite values - if ((diff * 0.0 != 0.0) || (pos_delta < diff)) - { - UnityTestResultsFailBegin(lineNumber); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat((float)expected); - UnityPrint(UnityStrWas); - UnityPrintFloat((float)actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- - -void UnityAssertDoubleSpecial(const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style) -{ - const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; - _U_SINT should_be_trait = ((_U_SINT)style & 1); - _U_SINT is_trait = !should_be_trait; - _U_SINT trait_index = style >> 1; - - UNITY_SKIP_EXECUTION; - - switch(style) - { - //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly - //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise - case UNITY_FLOAT_IS_INF: - case UNITY_FLOAT_IS_NOT_INF: - is_trait = isinf(actual) & ispos(actual); - break; - case UNITY_FLOAT_IS_NEG_INF: - case UNITY_FLOAT_IS_NOT_NEG_INF: - is_trait = isinf(actual) & isneg(actual); - break; - - //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. - case UNITY_FLOAT_IS_NAN: - case UNITY_FLOAT_IS_NOT_NAN: - is_trait = isnan(actual); - break; - - //A determinate number is non infinite and not NaN. (therefore the opposite of the two above) - case UNITY_FLOAT_IS_DET: - case UNITY_FLOAT_IS_NOT_DET: - if (isinf(actual) | isnan(actual)) - is_trait = 0; - else - is_trait = 1; - break; - - default: - break; - } - - if (is_trait != should_be_trait) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - if (!should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); - UnityPrint(UnityStrWas); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrintFloat(actual); -#else - if (should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - - -#endif // not UNITY_EXCLUDE_DOUBLE - -//----------------------------------------------- -void UnityAssertNumbersWithin( const _U_SINT delta, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - UNITY_SKIP_EXECUTION; - - if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) - { - if (actual > expected) - Unity.CurrentTestFailed = ((actual - expected) > delta); - else - Unity.CurrentTestFailed = ((expected - actual) > delta); - } - else - { - if ((_U_UINT)actual > (_U_UINT)expected) - Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > (_U_UINT)delta); - else - Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > (_U_UINT)delta); - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrDelta); - UnityPrintNumberByStyle(delta, style); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(expected, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(actual, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertEqualString(const char* expected, - const char* actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i; - - UNITY_SKIP_EXECUTION; - - // if both pointers not null compare the strings - if (expected && actual) - { - for (i = 0; expected[i] || actual[i]; i++) - { - if (expected[i] != actual[i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { // handle case of one pointers being null (if both null, test should pass) - if (expected != actual) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrintExpectedAndActualStrings(expected, actual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertEqualStringLen(const char* expected, - const char* actual, - const _UU32 length, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i; - - UNITY_SKIP_EXECUTION; - - // if both pointers not null compare the strings - if (expected && actual) - { - for (i = 0; (expected[i] || actual[i]) && i < length; i++) - { - if (expected[i] != actual[i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { // handle case of one pointers being null (if both null, test should pass) - if (expected != actual) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrintExpectedAndActualStringsLen(expected, actual, length); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - - -//----------------------------------------------- -void UnityAssertEqualStringArray( const char** expected, - const char** actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i, j = 0; - - UNITY_SKIP_EXECUTION; - - // if no elements, it's an error - if (num_elements == 0) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - do - { - // if both pointers not null compare the strings - if (expected[j] && actual[j]) - { - for (i = 0; expected[j][i] || actual[j][i]; i++) - { - if (expected[j][i] != actual[j][i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { // handle case of one pointers being null (if both null, test should pass) - if (expected[j] != actual[j]) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - if (num_elements > 1) - { - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((j), UNITY_DISPLAY_STYLE_UINT); - } - UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j])); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - } while (++j < num_elements); -} - -//----------------------------------------------- -void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 length, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; - UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; - _UU32 elements = num_elements; - _UU32 bytes; - - UNITY_SKIP_EXECUTION; - - if ((elements == 0) || (length == 0)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - ///////////////////////////////////// - bytes = length; - while (bytes--) - { - if (*ptr_exp != *ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrMemory); - if (num_elements > 1) - { - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - } - UnityPrint(UnityStrByte); - UnityPrintNumberByStyle((length - bytes - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); - } - ///////////////////////////////////// - - } -} - -//----------------------------------------------- -// Control Functions -//----------------------------------------------- - -void UnityFail(const char* msg, const UNITY_LINE_TYPE line) -{ - UNITY_SKIP_EXECUTION; - - UnityTestResultsBegin(Unity.TestFile, line); - UnityPrintFail(); - if (msg != NULL) - { - UNITY_OUTPUT_CHAR(':'); - -#ifndef UNITY_EXCLUDE_DETAILS - if (Unity.CurrentDetail1) - { - UnityPrint(UnityStrDetail1Name); - UnityPrint(Unity.CurrentDetail1); - if (Unity.CurrentDetail2) - { - UnityPrint(UnityStrDetail2Name); - UnityPrint(Unity.CurrentDetail2); - } - UnityPrint(UnityStrSpacer); - } -#endif - if (msg[0] != ' ') - { - UNITY_OUTPUT_CHAR(' '); - } - UnityPrint(msg); - } - - UNITY_FAIL_AND_BAIL; -} - -//----------------------------------------------- -void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) -{ - UNITY_SKIP_EXECUTION; - - UnityTestResultsBegin(Unity.TestFile, line); - UnityPrint(UnityStrIgnore); - if (msg != NULL) - { - UNITY_OUTPUT_CHAR(':'); - UNITY_OUTPUT_CHAR(' '); - UnityPrint(msg); - } - UNITY_IGNORE_AND_BAIL; -} - -//----------------------------------------------- -#if defined(UNITY_WEAK_ATTRIBUTE) - void setUp(void); - void tearDown(void); - UNITY_WEAK_ATTRIBUTE void setUp(void) { } - UNITY_WEAK_ATTRIBUTE void tearDown(void) { } -#elif defined(UNITY_WEAK_PRAGMA) -# pragma weak setUp - void setUp(void) { } -# pragma weak tearDown - void tearDown(void) { } -#else - void setUp(void); - void tearDown(void); -#endif -//----------------------------------------------- -void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) -{ - Unity.CurrentTestName = FuncName; - Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; - Unity.NumberOfTests++; - UNITY_CLR_DETAILS(); - if (TEST_PROTECT()) - { - setUp(); - Func(); - } - if (TEST_PROTECT() && !(Unity.CurrentTestIgnored)) - { - tearDown(); - } - UnityConcludeTest(); -} - -//----------------------------------------------- -void UnityBegin(const char* filename) -{ - Unity.TestFile = filename; - Unity.CurrentTestName = NULL; - Unity.CurrentTestLineNumber = 0; - Unity.NumberOfTests = 0; - Unity.TestFailures = 0; - Unity.TestIgnores = 0; - Unity.CurrentTestFailed = 0; - Unity.CurrentTestIgnored = 0; - - UNITY_CLR_DETAILS(); - UNITY_OUTPUT_START(); -} - -//----------------------------------------------- -int UnityEnd(void) -{ - UNITY_PRINT_EOL(); - UnityPrint(UnityStrBreaker); - UNITY_PRINT_EOL(); - UnityPrintNumber((_U_SINT)(Unity.NumberOfTests)); - UnityPrint(UnityStrResultsTests); - UnityPrintNumber((_U_SINT)(Unity.TestFailures)); - UnityPrint(UnityStrResultsFailures); - UnityPrintNumber((_U_SINT)(Unity.TestIgnores)); - UnityPrint(UnityStrResultsIgnored); - UNITY_PRINT_EOL(); - if (Unity.TestFailures == 0U) - { - UnityPrintOk(); - } - else - { - UnityPrintFail(); - } - UNITY_PRINT_EOL(); - UNITY_OUTPUT_COMPLETE(); - return (int)(Unity.TestFailures); -} - -//----------------------------------------------- +/* ========================================================================= + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +============================================================================ */ + +#include "unity.h" +#include + +#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; longjmp(Unity.AbortFrame, 1); } +#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; longjmp(Unity.AbortFrame, 1); } +/// return prematurely if we are already in failure or ignore state +#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} } + +struct _Unity Unity; + +const char UnityStrOk[] = "OK"; +const char UnityStrPass[] = "PASS"; +const char UnityStrFail[] = "FAIL"; +const char UnityStrIgnore[] = "IGNORE"; +const char UnityStrNull[] = "NULL"; +const char UnityStrSpacer[] = ". "; +const char UnityStrExpected[] = " Expected "; +const char UnityStrWas[] = " Was "; +const char UnityStrTo[] = " To "; +const char UnityStrElement[] = " Element "; +const char UnityStrByte[] = " Byte "; +const char UnityStrMemory[] = " Memory Mismatch."; +const char UnityStrDelta[] = " Values Not Within Delta "; +const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; +const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; +const char UnityStrNullPointerForActual[] = " Actual pointer was NULL"; +const char UnityStrNot[] = "Not "; +const char UnityStrInf[] = "Infinity"; +const char UnityStrNegInf[] = "Negative Infinity"; +const char UnityStrNaN[] = "NaN"; +const char UnityStrDet[] = "Determinate"; +const char UnityStrErrFloat[] = "Unity Floating Point Disabled"; +const char UnityStrErrDouble[] = "Unity Double Precision Disabled"; +const char UnityStrErr64[] = "Unity 64-bit Support Disabled"; +const char UnityStrBreaker[] = "-----------------------"; +const char UnityStrResultsTests[] = " Tests "; +const char UnityStrResultsFailures[] = " Failures "; +const char UnityStrResultsIgnored[] = " Ignored "; +const char UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; +const char UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; + +#ifdef UNITY_FLOAT_NEEDS_ZERO +// Dividing by these constants produces +/- infinity. +// The rationale is given in UnityAssertFloatIsInf's body. +static const _UF f_zero = 0.0f; +#endif + +// compiler-generic print formatting masks +const _U_UINT UnitySizeMask[] = +{ + 255u, // 0xFF + 65535u, // 0xFFFF + 65535u, + 4294967295u, // 0xFFFFFFFF + 4294967295u, + 4294967295u, + 4294967295u +#ifdef UNITY_SUPPORT_64 + ,0xFFFFFFFFFFFFFFFF +#endif +}; + +void UnityPrintFail(void); +void UnityPrintOk(void); + +//----------------------------------------------- +// Pretty Printers & Test Result Output Handlers +//----------------------------------------------- + +void UnityPrint(const char* string) +{ + const char* pch = string; + + if (pch != NULL) + { + while (*pch) + { + // printable characters plus CR & LF are printed + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + //write escaped carriage returns + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + //write escaped line feeds + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + // unprintable characters are shown as codes + else + { + UNITY_OUTPUT_CHAR('\\'); + UnityPrintNumberHex((_U_UINT)*pch, 2); + } + pch++; + } + } +} + +void UnityPrintLen(const char* string, const _UU32 length); +void UnityPrintLen(const char* string, const _UU32 length) +{ + const char* pch = string; + + if (pch != NULL) + { + while (*pch && (_UU32)(pch - string) < length) + { + // printable characters plus CR & LF are printed + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + //write escaped carriage returns + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + //write escaped line feeds + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + // unprintable characters are shown as codes + else + { + UNITY_OUTPUT_CHAR('\\'); + UnityPrintNumberHex((_U_UINT)*pch, 2); + } + pch++; + } + } +} + +//----------------------------------------------- +void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style) +{ + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + UnityPrintNumber(number); + } + else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) + { + UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] ); + } + else + { + UnityPrintNumberHex((_U_UINT)number, (char)((style & 0x000F) << 1)); + } +} + +//----------------------------------------------- +/// basically do an itoa using as little ram as possible +void UnityPrintNumber(const _U_SINT number_to_print) +{ + _U_UINT divisor = 1; + _U_UINT next_divisor; + _U_UINT number; + + if (number_to_print < 0) + { + //A negative number, including MIN negative + UNITY_OUTPUT_CHAR('-'); + number = (_U_UINT)(-number_to_print); + } + else + { + //Non-negative number + number = (_U_UINT)number_to_print; + } + + // figure out initial divisor + while (number / divisor > 9) + { + next_divisor = divisor * 10; + if (next_divisor > divisor) + divisor = next_divisor; + else + break; + } + + // now mod and print, then divide divisor + do + { + UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); + divisor /= 10; + } + while (divisor > 0); +} + +//----------------------------------------------- +/// basically do an itoa using as little ram as possible +void UnityPrintNumberUnsigned(const _U_UINT number) +{ + _U_UINT divisor = 1; + _U_UINT next_divisor; + + // figure out initial divisor + while (number / divisor > 9) + { + next_divisor = divisor * 10; + if (next_divisor > divisor) + divisor = next_divisor; + else + break; + } + + // now mod and print, then divide divisor + do + { + UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); + divisor /= 10; + } + while (divisor > 0); +} + +//----------------------------------------------- +void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print) +{ + _U_UINT nibble; + char nibbles = nibbles_to_print; + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + + while (nibbles > 0) + { + nibble = (number >> (--nibbles << 2)) & 0x0000000F; + if (nibble <= 9) + { + UNITY_OUTPUT_CHAR((char)('0' + nibble)); + } + else + { + UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); + } + } +} + +//----------------------------------------------- +void UnityPrintMask(const _U_UINT mask, const _U_UINT number) +{ + _U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1); + _US32 i; + + for (i = 0; i < UNITY_INT_WIDTH; i++) + { + if (current_bit & mask) + { + if (current_bit & number) + { + UNITY_OUTPUT_CHAR('1'); + } + else + { + UNITY_OUTPUT_CHAR('0'); + } + } + else + { + UNITY_OUTPUT_CHAR('X'); + } + current_bit = current_bit >> 1; + } +} + +//----------------------------------------------- +#ifdef UNITY_FLOAT_VERBOSE +#include +void UnityPrintFloat(_UF number) +{ + char TempBuffer[32]; + sprintf(TempBuffer, "%.6f", number); + UnityPrint(TempBuffer); +} +#endif + +//----------------------------------------------- + +void UnityPrintFail(void); +void UnityPrintFail(void) +{ + UnityPrint(UnityStrFail); +} + +void UnityPrintOk(void); +void UnityPrintOk(void) +{ + UnityPrint(UnityStrOk); +} + +//----------------------------------------------- +static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line); +static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) +{ +#ifndef UNITY_FIXTURES + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((_U_SINT)line); + UNITY_OUTPUT_CHAR(':'); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#else + UNITY_UNUSED(file); + UNITY_UNUSED(line); +#endif +} + +//----------------------------------------------- +static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line); +static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) +{ +#ifndef UNITY_FIXTURES + UnityTestResultsBegin(Unity.TestFile, line); +#else + UNITY_UNUSED(line); +#endif + UnityPrint(UnityStrFail); + UNITY_OUTPUT_CHAR(':'); +} + +//----------------------------------------------- +void UnityConcludeTest(void) +{ + if (Unity.CurrentTestIgnored) + { + Unity.TestIgnores++; + } + else if (!Unity.CurrentTestFailed) + { + UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); + UnityPrint(UnityStrPass); + } + else + { + Unity.TestFailures++; + } + + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + UNITY_PRINT_EOL(); +} + +//----------------------------------------------- +static void UnityAddMsgIfSpecified(const char* msg); +static void UnityAddMsgIfSpecified(const char* msg) +{ + if (msg) + { + UnityPrint(UnityStrSpacer); +#ifndef UNITY_EXCLUDE_DETAILS + if (Unity.CurrentDetail1) + { + UnityPrint(UnityStrDetail1Name); + UnityPrint(Unity.CurrentDetail1); + if (Unity.CurrentDetail2) + { + UnityPrint(UnityStrDetail2Name); + UnityPrint(Unity.CurrentDetail2); + } + UnityPrint(UnityStrSpacer); + } +#endif + UnityPrint(msg); + } +} + +//----------------------------------------------- +static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual); +static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) +{ + UnityPrint(UnityStrExpected); + if (expected != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(expected); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } + UnityPrint(UnityStrWas); + if (actual != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(actual); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } +} + +//----------------------------------------------- +static void UnityPrintExpectedAndActualStringsLen(const char* expected, const char* actual, const _UU32 length) +{ + UnityPrint(UnityStrExpected); + if (expected != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrintLen(expected, length); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } + UnityPrint(UnityStrWas); + if (actual != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrintLen(actual, length); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } +} + + + +//----------------------------------------------- +// Assertion & Control Helpers +//----------------------------------------------- + +static int UnityCheckArraysForNull(UNITY_INTERNAL_PTR expected, UNITY_INTERNAL_PTR actual, const UNITY_LINE_TYPE lineNumber, const char* msg) +{ + //return true if they are both NULL + if ((expected == NULL) && (actual == NULL)) + return 1; + + //throw error if just expected is NULL + if (expected == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForExpected); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + //throw error if just actual is NULL + if (actual == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForActual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + //return false if neither is NULL + return 0; +} + +//----------------------------------------------- +// Assertion Functions +//----------------------------------------------- + +void UnityAssertBits(const _U_SINT mask, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_SKIP_EXECUTION; + + if ((mask & expected) != (mask & actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintMask((_U_UINT)mask, (_U_UINT)expected); + UnityPrint(UnityStrWas); + UnityPrintMask((_U_UINT)mask, (_U_UINT)actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertEqualNumber(const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + UNITY_SKIP_EXECUTION; + + if (expected != actual) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + _UU32 elements = num_elements; + UNITY_INTERNAL_PTR ptr_exp = (UNITY_INTERNAL_PTR)expected; + UNITY_INTERNAL_PTR ptr_act = (UNITY_INTERNAL_PTR)actual; + + UNITY_SKIP_EXECUTION; + + if (elements == 0) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + // If style is UNITY_DISPLAY_STYLE_INT, we'll fall into the default case rather than the INT16 or INT32 (etc) case + // as UNITY_DISPLAY_STYLE_INT includes a flag for UNITY_DISPLAY_RANGE_AUTO, which the width-specific + // variants do not. Therefore remove this flag. + switch(style & (UNITY_DISPLAY_STYLE_T)(~UNITY_DISPLAY_RANGE_AUTO)) + { + case UNITY_DISPLAY_STYLE_HEX8: + case UNITY_DISPLAY_STYLE_INT8: + case UNITY_DISPLAY_STYLE_UINT8: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); + } + break; + case UNITY_DISPLAY_STYLE_HEX16: + case UNITY_DISPLAY_STYLE_INT16: + case UNITY_DISPLAY_STYLE_UINT16: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 2); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 2); + } + break; +#ifdef UNITY_SUPPORT_64 + case UNITY_DISPLAY_STYLE_HEX64: + case UNITY_DISPLAY_STYLE_INT64: + case UNITY_DISPLAY_STYLE_UINT64: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 8); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 8); + } + break; +#endif + default: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 4); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 4); + } + break; + } +} + +//----------------------------------------------- +#ifndef UNITY_EXCLUDE_FLOAT +void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, + UNITY_PTR_ATTRIBUTE const _UF* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual; + _UF diff, tol; + + UNITY_SKIP_EXECUTION; + + if (elements == 0) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + while (elements--) + { + diff = *ptr_expected - *ptr_actual; + if (diff < 0.0f) + diff = 0.0f - diff; + tol = UNITY_FLOAT_PRECISION * *ptr_expected; + if (tol < 0.0f) + tol = 0.0f - tol; + + //This first part of this condition will catch any NaN or Infinite values + if ((diff * 0.0f != 0.0f) || (diff > tol)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); +#ifdef UNITY_FLOAT_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat(*ptr_expected); + UnityPrint(UnityStrWas); + UnityPrintFloat(*ptr_actual); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_expected++; + ptr_actual++; + } +} + +//----------------------------------------------- +void UnityAssertFloatsWithin(const _UF delta, + const _UF expected, + const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UF diff = actual - expected; + _UF pos_delta = delta; + + UNITY_SKIP_EXECUTION; + + if (diff < 0.0f) + { + diff = 0.0f - diff; + } + if (pos_delta < 0.0f) + { + pos_delta = 0.0f - pos_delta; + } + + //This first part of this condition will catch any NaN or Infinite values + if ((diff * 0.0f != 0.0f) || (pos_delta < diff)) + { + UnityTestResultsFailBegin(lineNumber); +#ifdef UNITY_FLOAT_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat(expected); + UnityPrint(UnityStrWas); + UnityPrintFloat(actual); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertFloatSpecial(const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; + _U_SINT should_be_trait = ((_U_SINT)style & 1); + _U_SINT is_trait = !should_be_trait; + _U_SINT trait_index = style >> 1; + + UNITY_SKIP_EXECUTION; + + switch(style) + { + //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly + //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = isinf(actual) & ispos(actual); + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = isinf(actual) & isneg(actual); + break; + + //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = isnan(actual); + break; + + //A determinate number is non infinite and not NaN. (therefore the opposite of the two above) + case UNITY_FLOAT_IS_DET: + case UNITY_FLOAT_IS_NOT_DET: + if (isinf(actual) | isnan(actual)) + is_trait = 0; + else + is_trait = 1; + break; + + default: + break; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifdef UNITY_FLOAT_VERBOSE + UnityPrintFloat(actual); +#else + if (should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#endif //not UNITY_EXCLUDE_FLOAT + +//----------------------------------------------- +#ifndef UNITY_EXCLUDE_DOUBLE +void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, + UNITY_PTR_ATTRIBUTE const _UD* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual; + _UD diff, tol; + + UNITY_SKIP_EXECUTION; + + if (elements == 0) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + while (elements--) + { + diff = *ptr_expected - *ptr_actual; + if (diff < 0.0) + diff = 0.0 - diff; + tol = UNITY_DOUBLE_PRECISION * *ptr_expected; + if (tol < 0.0) + tol = 0.0 - tol; + + //This first part of this condition will catch any NaN or Infinite values + if ((diff * 0.0 != 0.0) || (diff > tol)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); +#ifdef UNITY_DOUBLE_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat((float)(*ptr_expected)); + UnityPrint(UnityStrWas); + UnityPrintFloat((float)(*ptr_actual)); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_expected++; + ptr_actual++; + } +} + +//----------------------------------------------- +void UnityAssertDoublesWithin(const _UD delta, + const _UD expected, + const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UD diff = actual - expected; + _UD pos_delta = delta; + + UNITY_SKIP_EXECUTION; + + if (diff < 0.0) + { + diff = 0.0 - diff; + } + if (pos_delta < 0.0) + { + pos_delta = 0.0 - pos_delta; + } + + //This first part of this condition will catch any NaN or Infinite values + if ((diff * 0.0 != 0.0) || (pos_delta < diff)) + { + UnityTestResultsFailBegin(lineNumber); +#ifdef UNITY_DOUBLE_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat((float)expected); + UnityPrint(UnityStrWas); + UnityPrintFloat((float)actual); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- + +void UnityAssertDoubleSpecial(const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; + _U_SINT should_be_trait = ((_U_SINT)style & 1); + _U_SINT is_trait = !should_be_trait; + _U_SINT trait_index = style >> 1; + + UNITY_SKIP_EXECUTION; + + switch(style) + { + //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly + //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = isinf(actual) & ispos(actual); + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = isinf(actual) & isneg(actual); + break; + + //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = isnan(actual); + break; + + //A determinate number is non infinite and not NaN. (therefore the opposite of the two above) + case UNITY_FLOAT_IS_DET: + case UNITY_FLOAT_IS_NOT_DET: + if (isinf(actual) | isnan(actual)) + is_trait = 0; + else + is_trait = 1; + break; + + default: + break; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifdef UNITY_DOUBLE_VERBOSE + UnityPrintFloat(actual); +#else + if (should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + + +#endif // not UNITY_EXCLUDE_DOUBLE + +//----------------------------------------------- +void UnityAssertNumbersWithin( const _U_SINT delta, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + UNITY_SKIP_EXECUTION; + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (actual > expected) + Unity.CurrentTestFailed = ((actual - expected) > delta); + else + Unity.CurrentTestFailed = ((expected - actual) > delta); + } + else + { + if ((_U_UINT)actual > (_U_UINT)expected) + Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > (_U_UINT)delta); + else + Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > (_U_UINT)delta); + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrDelta); + UnityPrintNumberByStyle(delta, style); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 i; + + UNITY_SKIP_EXECUTION; + + // if both pointers not null compare the strings + if (expected && actual) + { + for (i = 0; expected[i] || actual[i]; i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { // handle case of one pointers being null (if both null, test should pass) + if (expected != actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrintExpectedAndActualStrings(expected, actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertEqualStringLen(const char* expected, + const char* actual, + const _UU32 length, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 i; + + UNITY_SKIP_EXECUTION; + + // if both pointers not null compare the strings + if (expected && actual) + { + for (i = 0; (expected[i] || actual[i]) && i < length; i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { // handle case of one pointers being null (if both null, test should pass) + if (expected != actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrintExpectedAndActualStringsLen(expected, actual, length); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + + +//----------------------------------------------- +void UnityAssertEqualStringArray( const char** expected, + const char** actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 i, j = 0; + + UNITY_SKIP_EXECUTION; + + // if no elements, it's an error + if (num_elements == 0) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + do + { + // if both pointers not null compare the strings + if (expected[j] && actual[j]) + { + for (i = 0; expected[j][i] || actual[j][i]; i++) + { + if (expected[j][i] != actual[j][i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { // handle case of one pointers being null (if both null, test should pass) + if (expected[j] != actual[j]) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((j), UNITY_DISPLAY_STYLE_UINT); + } + UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j])); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + } while (++j < num_elements); +} + +//----------------------------------------------- +void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const _UU32 length, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; + _UU32 elements = num_elements; + _UU32 bytes; + + UNITY_SKIP_EXECUTION; + + if ((elements == 0) || (length == 0)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + while (elements--) + { + ///////////////////////////////////// + bytes = length; + while (bytes--) + { + if (*ptr_exp != *ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrMemory); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + } + UnityPrint(UnityStrByte); + UnityPrintNumberByStyle((length - bytes - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); + } + ///////////////////////////////////// + + } +} + +//----------------------------------------------- +// Control Functions +//----------------------------------------------- + +void UnityFail(const char* msg, const UNITY_LINE_TYPE line) +{ + UNITY_SKIP_EXECUTION; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrintFail(); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + +#ifndef UNITY_EXCLUDE_DETAILS + if (Unity.CurrentDetail1) + { + UnityPrint(UnityStrDetail1Name); + UnityPrint(Unity.CurrentDetail1); + if (Unity.CurrentDetail2) + { + UnityPrint(UnityStrDetail2Name); + UnityPrint(Unity.CurrentDetail2); + } + UnityPrint(UnityStrSpacer); + } +#endif + if (msg[0] != ' ') + { + UNITY_OUTPUT_CHAR(' '); + } + UnityPrint(msg); + } + + UNITY_FAIL_AND_BAIL; +} + +//----------------------------------------------- +void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) +{ + UNITY_SKIP_EXECUTION; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrIgnore); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(msg); + } + UNITY_IGNORE_AND_BAIL; +} + +//----------------------------------------------- +#if defined(UNITY_WEAK_ATTRIBUTE) + void setUp(void); + void tearDown(void); + UNITY_WEAK_ATTRIBUTE void setUp(void) { } + UNITY_WEAK_ATTRIBUTE void tearDown(void) { } +#elif defined(UNITY_WEAK_PRAGMA) +# pragma weak setUp + void setUp(void) { } +# pragma weak tearDown + void tearDown(void) { } +#else + void setUp(void); + void tearDown(void); +#endif +//----------------------------------------------- +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) +{ + Unity.CurrentTestName = FuncName; + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; + Unity.NumberOfTests++; + UNITY_CLR_DETAILS(); + if (TEST_PROTECT()) + { + setUp(); + Func(); + } + if (TEST_PROTECT() && !(Unity.CurrentTestIgnored)) + { + tearDown(); + } + UnityConcludeTest(); +} + +//----------------------------------------------- +void UnityBegin(const char* filename) +{ + Unity.TestFile = filename; + Unity.CurrentTestName = NULL; + Unity.CurrentTestLineNumber = 0; + Unity.NumberOfTests = 0; + Unity.TestFailures = 0; + Unity.TestIgnores = 0; + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + + UNITY_CLR_DETAILS(); + UNITY_OUTPUT_START(); +} + +//----------------------------------------------- +int UnityEnd(void) +{ + UNITY_PRINT_EOL(); + UnityPrint(UnityStrBreaker); + UNITY_PRINT_EOL(); + UnityPrintNumber((_U_SINT)(Unity.NumberOfTests)); + UnityPrint(UnityStrResultsTests); + UnityPrintNumber((_U_SINT)(Unity.TestFailures)); + UnityPrint(UnityStrResultsFailures); + UnityPrintNumber((_U_SINT)(Unity.TestIgnores)); + UnityPrint(UnityStrResultsIgnored); + UNITY_PRINT_EOL(); + if (Unity.TestFailures == 0U) + { + UnityPrintOk(); + } + else + { + UnityPrintFail(); + } + UNITY_PRINT_EOL(); + UNITY_OUTPUT_COMPLETE(); + return (int)(Unity.TestFailures); +} + +//-----------------------------------------------