JFIFXX    $.' ",#(7),01444'9=82<.342  2!!22222222222222222222222222222222222222222222222222"4 ,PG"Z_4˷kjزZ,F+_z,© zh6٨icfu#ډb_N?wQ5-~I8TK<5oIv-k_U_~bMdӜUHh?]EwQk{_}qFW7HTՑYF?_'ϔ_Ջt=||I 6έ"D/[k9Y8ds|\Ҿp6Ҵ].6znopM[mei$[soᘨ˸ nɜG-ĨUycP3.DBli;hjx7Z^NhN3u{:jx힞#M&jL P@_ P&o89@Sz6t7#Oߋ s}YfTlmrZ)'Nk۞pw\Tȯ?8`Oi{wﭹW[r Q4F׊3m&L=h3z~#\l :F,j@ ʱwQT8"kJO6֚l}R>ډK]y&p}b;N1mr$|7>e@BTM*-iHgD) Em|ؘbҗaҾt4oG*oCNrPQ@z,|?W[0:n,jWiEW$~/hp\?{(0+Y8rΟ+>S-SVN;}s?. w9˟<Mq4Wv'{)01mBVW[8/< %wT^5b)iM pgN&ݝVO~qu9 !J27$O-! :%H ـyΠM=t{!S oK8txA& j0 vF Y|y ~6@c1vOpIg4lODL Rcj_uX63?nkWyf;^*B @~a`Eu+6L.ü>}y}_O6͐:YrGXkGl^w~㒶syIu! W XN7BVO!X2wvGRfT#t/?%8^WaTGcLMI(J1~8?aT ]ASE(*E} 2#I/׍qz^t̔bYz4xt){ OH+(EA&NXTo"XC')}Jzp ~5}^+6wcQ|LpdH}(.|kc4^"Z?ȕ a<L!039C EuCFEwç ;n?*oB8bʝ'#RqfM}7]s2tcS{\icTx;\7KPʇ Z O-~c>"?PEO8@8GQgaՎ󁶠䧘_%#r>1zaebqcPѵn#L =׀t L7`VA{C:ge@w1 Xp3c3ġpM"'-@n4fGB3DJ8[JoߐgK)ƛ$ 83+ 6ʻ SkI*KZlT _`?KQKdB`s}>`*>,*@JdoF*弝O}ks]yߘc1GV<=776qPTtXԀ!9*44Tހ3XΛex46YD  BdemDa\_l,G/֌7Y](xTt^%GE4}bTڹ;Y)BQu>J/J ⮶.XԄjݳ+Ed r5_D1 o Bx΢#<W8R6@gM. drD>(otU@x=~v2 ӣdoBd3eO6㣷ݜ66YQz`S{\P~z m5{J/L1xO\ZFu>ck#&:`$ai>2ΔloF[hlEܺΠk:)` $[69kOw\|8}ބ:񶐕IA1/=2[,!.}gN#ub ~݊}34qdELc$"[qU硬g^%B zrpJru%v\h1Yne`ǥ:gpQM~^Xi `S:V29.PV?Bk AEvw%_9CQwKekPؠ\;Io d{ ߞoc1eP\ `E=@KIRYK2NPlLɀ)&eB+ь( JTx_?EZ }@ 6U뙢طzdWIn` D噥[uV"G&Ú2g}&m?ċ"Om# {ON"SXNeysQ@FnVgdX~nj]J58up~.`r\O,ư0oS _Ml4kv\JSdxSW<AeIX$Iw:Sy›R9Q[,5;@]%u@ *rolbI  +%m:͇ZVủθau,RW33 dJeTYE.Mϧ-oj3+yy^cVO9NV\nd1 !͕_)av;թMlWR1)ElP;yوÏu 3k5Pr6<⒲l!˞*u־n!l:UNW %Chx8vL'X@*)̮ˍ D-M+JUkvK+x8cY?Ԡ~3mo|u@[XeYC\Kpx8oCC&N~3-H MXsu<`~"WL$8ξ3a)|:@m\^`@ҷ)5p+6p%i)P Mngc#0AruzRL+xSS?ʮ}()#tmˇ!0}}y$6Lt;$ʳ{^6{v6ķܰgVcnn ~zx«,2u?cE+ȘH؎%Za)X>uWTzNyosFQƤ$*&LLXL)1" LeOɟ9=:tZcŽY?ӭVwv~,Yrۗ|yGaFC.+ v1fήJ]STBn5sW}y$~z'c 8  ,! pVNSNNqy8z˱A4*'2n<s^ǧ˭PJޮɏUGLJ*#i}K%,)[z21z ?Nin1?TIR#m-1lA`fT5+ܐcq՝ʐ,3f2Uեmab#ŠdQy>\)SLYw#.ʑf ,"+w~N'cO3FN<)j&,- љ֊_zSTǦw>?nU仆Ve0$CdrP m׈eXmVu L.bֹ [Դaզ*\y8Է:Ez\0KqC b̘cөQ=0YsNS.3.Oo:#v7[#߫ 5܎LEr49nCOWlG^0k%;YߝZǓ:S#|}y,/kLd TA(AI$+I3;Y*Z}|ӧOdv..#:nf>>ȶITX 8y"dR|)0=n46ⲑ+ra ~]R̲c?6(q;5% |uj~z8R=XIV=|{vGj\gcqz؋%Mߍ1y#@f^^>N#x#۹6Y~?dfPO{P4Vu1E1J *|%JN`eWuzk M6q t[ gGvWIGu_ft5j"Y:Tɐ*; e54q$C2d} _SL#mYpO.C;cHi#֩%+) ӍƲVSYźg |tj38r|V1#;.SQA[S#`n+$$I P\[@s(EDzP])8G#0B[ىXIIq<9~[Z멜Z⊔IWU&A>P~#dp]9 "cP Md?٥Ifتuk/F9c*9Ǎ:ØFzn*@|Iށ9N3{'['ͬҲ4#}!V Fu,,mTIkv C7vB6kT91*l '~ƞFlU'M ][ΩũJ_{iIn$L jOdxkza۪#EClx˘oVɞljr)/,߬hL#^Lф,íMƁe̩NBLiLq}(q6IçJ$WE$:=#(KBzђ xlx?>Պ+>W,Ly!_DŌlQ![ SJ1ƐY}b,+Loxɓ)=yoh@꥟/Iѭ=Py9 ۍYӘe+pJnϱ?V\SO%(t =?MR[Șd/ nlB7j !;ӥ/[-A>dNsLj ,ɪv=1c.SQO3UƀܽE̻9GϷD7(}Ävӌ\y_0[w <΍>a_[0+LF.޺f>oNTq;y\bՃyjH<|q-eɏ_?_9+PHp$[uxK wMwNی'$Y2=qKBP~Yul:[<F12O5=d]Ysw:ϮEj,_QXz`H1,#II dwrP˂@ZJVy$\y{}^~[:NߌUOdؾe${p>G3cĖlʌ ת[`ϱ-WdgIig2 }s ؤ(%#sS@~3XnRG~\jc3vӍLM[JBTs3}jNʖW;7ç?=XF=-=qߚ#='c7ڑWI(O+=:uxqe2zi+kuGR0&eniT^J~\jyp'dtGsO39* b#Ɋ p[BwsT>d4ۧsnvnU_~,vƜJ1s QIz)(lv8MU=;56Gs#KMP=LvyGd}VwWBF'à ?MHUg2 !p7Qjڴ=ju JnA suMeƆҔ!)'8Ϣٔޝ(Vpצ֖d=ICJǠ{qkԭ߸i@Ku|p=..*+xz[Aqġ#s2aƊRR)*HRsi~a &fMP-KL@ZXy'x{}Zm+:)) IJ-iu ܒH'L(7yGӜq j 6ߌg1go,kرtY?W,pefOQS!K۟cҒA|սj>=⬒˧L[ ߿2JaB~Ru:Q] 0H~]7ƼI(}cq 'ήETq?fabӥvr )o-Q_'ᴎoK;Vo%~OK *bf:-ťIR`B5!RB@ï u ̯e\_U_ gES3QTaxU<~c?*#]MW,[8Oax]1bC|踤Plw5V%){t<d50iXSUm:Z┵i"1^B-PhJ&)O*DcWvM)}Pܗ-q\mmζZ-l@}aE6F@&Sg@ݚM ȹ 4#p\HdYDoH"\..RBHz_/5˘6KhJRPmƶim3,#ccoqa)*PtRmk7xDE\Y閣_X<~)c[[BP6YqS0%_;Àv~| VS؇ 'O0F0\U-d@7SJ*z3nyPOm~P3|Yʉr#CSN@ ƮRN)r"C:: #qbY. 6[2K2uǦHYRQMV G$Q+.>nNHq^ qmMVD+-#*U̒ p욳u:IBmPV@Or[b= 1UE_NmyKbNOU}the`|6֮P>\2PVIDiPO;9rmAHGWS]J*_G+kP2KaZH'KxWMZ%OYDRc+o?qGhmdSoh\D|:WUAQc yTq~^H/#pCZTI1ӏT4"ČZ}`w#*,ʹ 0i課Om*da^gJ݅{le9uF#Tֲ̲ٞC"qߍ ոޑo#XZTp@ o8(jdxw],f`~|,s^f1t|m򸄭/ctr5s79Q4H1꠲BB@l9@C+wpxu£Yc9?`@#omHs2)=2.ljg9$YS%*LRY7Z,*=䷘$armoϰUW.|rufIGwtZwo~5 YյhO+=8fF)W7L9lM̘·Y֘YLf큹pRF99.A "wz=E\Z'a 2Ǚ#;'}G*l^"q+2FQ hjkŦ${ޮ-T٭cf|3#~RJt$b(R(rdx >U b&9,>%E\ Άe$'q't*אެb-|dSBOO$R+H)܎K1m`;J2Y~9Og8=vqD`K[F)k[1m޼cn]skz$@)!I x՝"v9=ZA=`Ɠi :E)`7vI}dYI_ o:obo 3Q&D&2= Ά;>hy.*ⅥSӬ+q&j|UƧ}J0WW< ۋS)jQRjƯrN)Gű4Ѷ(S)Ǣ8iW52No˓ ۍ%5brOnL;n\G=^UdI8$&h'+(cȁ߫klS^cƗjԌEꭔgFȒ@}O*;evWVYJ\]X'5ղkFb 6Ro՜mi Ni>J?lPmU}>_Z&KKqrIDՉ~q3fL:Se>E-G{L6pe,8QIhaXaUA'ʂs+טIjP-y8ۈZ?J$WP Rs]|l(ԓsƊio(S0Y 8T97.WiLc~dxcE|2!XKƘਫ਼$((6~|d9u+qd^389Y6L.I?iIq9)O/뚅OXXVZF[یgQLK1RҖr@v#XlFНyS87kF!AsM^rkpjPDyS$Nqnxҍ!Uf!ehi2m`YI9r6 TFC}/y^Η5d'9A-J>{_l+`A['յϛ#w:݅%X}&PStQ"-\縵/$ƗhXb*yBS;Wջ_mcvt?2}1;qSdd~u:2k52R~z+|HE!)Ǟl7`0<,2*Hl-x^'_TVgZA'j ^2ΪN7t?w x1fIzC-ȖK^q;-WDvT78Z hK(P:Q- 8nZ܃e貾<1YT<,"6{/ ?͟|1:#gW>$dJdB=jf[%rE^il:BxSּ1հ,=*7 fcG#q eh?27,!7x6nLC4x},GeǝtC.vS F43zz\;QYC,6~;RYS/6|25vTimlv& nRh^ejRLGf? ۉҬܦƩ|Ȱ>3!viʯ>vオX3e_1zKȗ\qHS,EW[㺨uch⍸O}a>q6n6N6qN ! 1AQaq0@"2BRb#Pr3C`Scst$4D%Td ?Na3mCwxAmqmm$4n淿t'C"wzU=D\R+wp+YT&պ@ƃ3ޯ?AﶂaŘ@-Q=9Dռѻ@MVP܅G5fY6# ?0UQ,IX(6ڵ[DIMNލc&υj\XR|,4 jThAe^db#$]wOӪ1y%LYm뭛CUƃߜ}Cy1XνmF8jI]HۺиE@Ii;r8ӭVFՇ| &?3|xBMuSGe=Ӕ#BE5GY!z_eqр/W>|-Ci߇t1ޯќdR3ug=0 5[?#͏qcfH{ ?u=??ǯ}ZzhmΔBFTWPxs}G93 )gGR<>r h$'nchPBjJҧH -N1N?~}-q!=_2hcMlvY%UE@|vM2.Y[|y"EïKZF,ɯ?,q?vM 80jx";9vk+ ֧ ȺU?%vcVmA6Qg^MA}3nl QRNl8kkn'(M7m9وq%ޟ*h$Zk"$9: ?U8Sl,,|ɒxH(ѷGn/Q4PG%Ա8N! &7;eKM749R/%lc>x;>C:th?aKXbheᜋ^$Iհ hr7%F$EFdt5+(M6tÜUU|zW=aTsTgdqPQb'm1{|YXNb P~F^F:k6"j! Ir`1&-$Bevk:y#ywI0x=D4tUPZHڠ底taP6b>xaQ# WeFŮNjpJ* mQN*I-*ȩFg3 5Vʊɮa5FO@{NX?H]31Ri_uѕ 0 F~:60p͈SqX#a5>`o&+<2D: ڝ$nP*)N|yEjF5ټeihyZ >kbHavh-#!Po=@k̆IEN@}Ll?jO߭ʞQ|A07xwt!xfI2?Z<ץTcUj]陎Ltl }5ϓ$,Omˊ;@OjEj(ا,LXLOЦ90O .anA7j4 W_ٓzWjcBy՗+EM)dNg6y1_xp$Lv:9"zpʙ$^JԼ*ϭo=xLj6Ju82AH3$ٕ@=Vv]'qEz;I˼)=ɯx /W(Vp$ mu񶤑OqˎTr㠚xsrGCbypG1ߠw e8$⿄/M{*}W]˷.CK\ުx/$WPwr |i&}{X >$-l?-zglΆ(FhvS*b߲ڡn,|)mrH[a3ר[13o_U3TC$(=)0kgP u^=4 WYCҸ:vQרXàtkm,t*^,}D* "(I9R>``[~Q]#afi6l86:,ssN6j"A4IuQ6E,GnHzSHOuk5$I4ؤQ9@CwpBGv[]uOv0I4\yQѸ~>Z8Taqޣ;za/SI:ܫ_|>=Z8:SUIJ"IY8%b8H:QO6;7ISJҌAά3>cE+&jf$eC+z;V rʺmyeaQf&6ND.:NTvm<- uǝ\MvZYNNT-A>jr!SnO 13Ns%3D@`ܟ 1^c< aɽ̲Xë#w|ycW=9I*H8p^(4՗karOcWtO\ƍR8'KIQ?5>[}yUײ -h=% qThG2)"ו3]!kB*pFDlA,eEiHfPs5H:Փ~H0DتDIhF3c2E9H5zԑʚiX=:mxghd(v׊9iSOd@0ڽ:p5h-t&Xqӕ,ie|7A2O%PEhtjY1wЃ!  ࢽMy7\a@ţJ 4ȻF@o̒?4wx)]P~u57X 9^ܩU;Iꭆ 5 eK27({|Y׎ V\"Z1 Z}(Ǝ"1S_vE30>p; ΝD%xW?W?vo^Vidr[/&>~`9Why;R ;;ɮT?r$g1KACcKl:'3 cﳯ*"t8~l)m+U,z`(>yJ?h>]vЍG*{`;y]IT ;cNUfo¾h/$|NS1S"HVT4uhǜ]v;5͠x'C\SBplh}N ABx%ޭl/Twʽ]D=Kžr㻠l4SO?=k M: cCa#ha)ѐxcsgPiG{+xQI= zԫ+ 8"kñj=|c yCF/*9жh{ ?4o kmQNx;Y4膚aw?6>e]Qr:g,i"ԩA*M7qB?ӕFhV25r[7 Y }LR}*sg+xr2U=*'WSZDW]WǞ<叓{$9Ou4y90-1'*D`c^o?(9uݐ'PI& fJݮ:wSjfP1F:X H9dԯ˝[_54 }*;@ܨ ðynT?ןd#4rGͨH1|-#MrS3G3).᧏3vz֑r$G"`j 1tx0<ƆWh6y6,œGagAyb)hDß_mü gG;evݝnQ C-*oyaMI><]obD":GA-\%LT8c)+y76oQ#*{(F⽕y=rW\p۩cA^e6KʐcVf5$'->ՉN"F"UQ@fGb~#&M=8טJNu9D[̤so~ G9TtW^g5y$bY'سǴ=U-2 #MCt(i lj@Q 5̣i*OsxKf}\M{EV{υƇ);HIfeLȣr2>WIȂ6ik 5YOxȺ>Yf5'|H+98pjn.OyjY~iw'l;s2Y:'lgꥴ)o#'SaaKZ m}`169n"xI *+ }FP"l45'ZgE8?[X7(.Q-*ތL@̲v.5[=t\+CNܛ,gSQnH}*FG16&:t4ُ"Ạ$b |#rsaT ]ӽDP7ո0y)e$ٕvIh'QEAm*HRI=: 4牢) %_iNݧl] NtGHL ɱg<1V,J~ٹ"KQ 9HS9?@kr;we݁]I!{ @G["`J:n]{cAEVʆ#U96j#Ym\qe4hB7Cdv\MNgmAyQL4uLjj9#44tl^}LnR!t±]rh6ٍ>yҏNfU  Fm@8}/ujb9he:AyծwGpΧh5l}3p468)Udc;Us/֔YX1O2uqs`hwgr~{ RmhN؎*q 42*th>#E#HvOq}6e\,Wk#Xb>p}դ3T5†6[@Py*n|'f֧>lư΂̺SU'*qp_SM 'c6m ySʨ;MrƋmKxo,GmPAG:iw9}M(^V$ǒѽ9| aJSQarB;}ٻ֢2%Uc#gNaݕ'v[OY'3L3;,p]@S{lsX'cjwk'a.}}& dP*bK=ɍ!;3ngΊUߴmt'*{,=SzfD Ako~Gaoq_mi}#mPXhύmxǍ΂巿zfQc|kc?WY$_Lvl߶c`?ljݲˏ!V6UЂ(A4y)HpZ_x>eR$/`^'3qˏ-&Q=?CFVR DfV9{8gnh(P"6[D< E~0<@`G6Hгcc cK.5DdB`?XQ2ٿyqo&+1^ DW0ꊩG#QnL3c/x 11[yxპCWCcUĨ80me4.{muI=f0QRls9f9~fǨa"@8ȁQ#cicG$Gr/$W(WV"m7[mAmboD j۳ l^kh׽ # iXnveTka^Y4BNĕ0 !01@Q"2AaPq3BR?@4QT3,㺠W[=JKϞ2r^7vc:9 EߴwS#dIxu:Hp9E! V 2;73|F9Y*ʬFDu&y؟^EAA(ɩ^GV:ݜDy`Jr29ܾ㝉[E;FzxYGUeYC v-txIsםĘqEb+P\ :>iC';k|zرny]#ǿbQw(r|ӹs[D2v-%@;8<a[\o[ϧwI!*0krs)[J9^ʜp1) "/_>o<1AEy^C`x1'ܣnps`lfQ):lb>MejH^?kl3(z:1ŠK&?Q~{ٺhy/[V|6}KbXmn[-75q94dmc^h X5G-}دBޟ |rtMV+]c?-#ڛ^ǂ}LkrOu>-Dry D?:ޞUǜ7V?瓮"#rչģVR;n/_ ؉vݶe5db9/O009G5nWJpA*r9>1.[tsFnQ V 77R]ɫ8_0<՜IFu(v4Fk3E)N:yڮeP`1}$WSJSQNjٺ޵#lј(5=5lǏmoWv-1v,Wmn߀$x_DȬ0¤#QR[Vkzmw"9ZG7'[=Qj8R?zf\a=OU*oBA|G254 p.w7  &ξxGHp B%$gtЏ򤵍zHNuЯ-'40;_3 !01"@AQa2Pq#3BR?ʩcaen^8F<7;EA{EÖ1U/#d1an.1ě0ʾRh|RAo3m3 % 28Q yφHTo7lW>#i`qca m,B-j݋'mR1Ήt>Vps0IbIC.1Rea]H64B>o]($Bma!=?B KǾ+Ծ"nK*+[T#{EJSQs5:U\wĐf3܆&)IԆwE TlrTf6Q|Rh:[K zc֧GC%\_a84HcObiؖV7H )*ģK~Xhչ04?0 E<}3#u? |gS6ꊤ|I#Hڛ աwX97Ŀ%SLy6č|Fa 8b$sקhb9RAu7˨pČ_\*w묦F 4D~f|("mNKiS>$d7SlA/²SL|6N}S˯g]6; #. 403WebShell
403Webshell
Server IP : 173.199.190.172  /  Your IP : 216.73.216.48
Web Server : Apache
System : Linux chs1.nescrow.com.ng 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64
User : oysipaoygov ( 1026)
PHP Version : 5.6.40
Disable Function : exec,passthru,shell_exec,system
MySQL : ON  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/share/gettext/intl/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/share/gettext/intl/setlocale.c
/* setlocale() function that respects the locale chosen by the user.
   Copyright (C) 2009, 2015-2016 Free Software Foundation, Inc.
   Written by Bruno Haible <bruno@clisp.org>, 2009.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation; either version 2.1 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

/* Override setlocale() and newlocale() so that when the default locale is
   requested (locale = "") and no relevant environment variable is set, the
   locale chosen by the user is used.
   This matters on MacOS X 10 and Windows.
   See the comments in localename.c, function gl_locale_name_default.  */

#include <locale.h>
#include <stdlib.h>
#include <string.h>

/* When building a DLL, we must export some functions.  Note that because
   the functions are only defined for binary backward compatibility, we
   don't need to use __declspec(dllimport) in any case.  */
#if HAVE_VISIBILITY && BUILDING_DLL
# define DLL_EXPORTED __attribute__((__visibility__("default")))
#elif defined _MSC_VER && BUILDING_DLL
# define DLL_EXPORTED __declspec(dllexport)
#else
# define DLL_EXPORTED
#endif

#include "gettextP.h"

#if (defined __APPLE__ && defined __MACH__) || defined _WIN32 || defined __WIN32__ || defined __CYGWIN__

# undef setlocale
# undef newlocale

/* Return string representation of locale category CATEGORY.  */
static const char *
category_to_name (int category)
{
  const char *retval;

  switch (category)
  {
  case LC_COLLATE:
    retval = "LC_COLLATE";
    break;
  case LC_CTYPE:
    retval = "LC_CTYPE";
    break;
  case LC_MONETARY:
    retval = "LC_MONETARY";
    break;
  case LC_NUMERIC:
    retval = "LC_NUMERIC";
    break;
  case LC_TIME:
    retval = "LC_TIME";
    break;
  case LC_MESSAGES:
    retval = "LC_MESSAGES";
    break;
  default:
    /* If you have a better idea for a default value let me know.  */
    retval = "LC_XXX";
  }

  return retval;
}

# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__

/* The native Win32 setlocale() function expects locale names of the form
   "German" or "German_Germany" or "DEU", but not "de" or "de_DE".  We need
   to convert the names from the form with ISO 639 language code and ISO 3166
   country code to the form with English names or with three-letter identifier.
   The three-letter identifiers known by a Windows XP SP2 or SP3 are:
     AFK  Afrikaans_South Africa.1252
     ARA  Arabic_Saudi Arabia.1256
     ARB  Arabic_Lebanon.1256
     ARE  Arabic_Egypt.1256
     ARG  Arabic_Algeria.1256
     ARH  Arabic_Bahrain.1256
     ARI  Arabic_Iraq.1256
     ARJ  Arabic_Jordan.1256
     ARK  Arabic_Kuwait.1256
     ARL  Arabic_Libya.1256
     ARM  Arabic_Morocco.1256
     ARO  Arabic_Oman.1256
     ARQ  Arabic_Qatar.1256
     ARS  Arabic_Syria.1256
     ART  Arabic_Tunisia.1256
     ARU  Arabic_U.A.E..1256
     ARY  Arabic_Yemen.1256
     AZE  Azeri (Latin)_Azerbaijan.1254
     BEL  Belarusian_Belarus.1251
     BGR  Bulgarian_Bulgaria.1251
     BSB  Bosnian_Bosnia and Herzegovina.1250
     BSC  Bosnian (Cyrillic)_Bosnia and Herzegovina.1250  (wrong encoding!)
     CAT  Catalan_Spain.1252
     CHH  Chinese_Hong Kong S.A.R..950
     CHI  Chinese_Singapore.936
     CHS  Chinese_People's Republic of China.936
     CHT  Chinese_Taiwan.950
     CSY  Czech_Czech Republic.1250
     CYM  Welsh_United Kingdom.1252
     DAN  Danish_Denmark.1252
     DEA  German_Austria.1252
     DEC  German_Liechtenstein.1252
     DEL  German_Luxembourg.1252
     DES  German_Switzerland.1252
     DEU  German_Germany.1252
     ELL  Greek_Greece.1253
     ENA  English_Australia.1252
     ENB  English_Caribbean.1252
     ENC  English_Canada.1252
     ENG  English_United Kingdom.1252
     ENI  English_Ireland.1252
     ENJ  English_Jamaica.1252
     ENL  English_Belize.1252
     ENP  English_Republic of the Philippines.1252
     ENS  English_South Africa.1252
     ENT  English_Trinidad and Tobago.1252
     ENU  English_United States.1252
     ENW  English_Zimbabwe.1252
     ENZ  English_New Zealand.1252
     ESA  Spanish_Panama.1252
     ESB  Spanish_Bolivia.1252
     ESC  Spanish_Costa Rica.1252
     ESD  Spanish_Dominican Republic.1252
     ESE  Spanish_El Salvador.1252
     ESF  Spanish_Ecuador.1252
     ESG  Spanish_Guatemala.1252
     ESH  Spanish_Honduras.1252
     ESI  Spanish_Nicaragua.1252
     ESL  Spanish_Chile.1252
     ESM  Spanish_Mexico.1252
     ESN  Spanish_Spain.1252
     ESO  Spanish_Colombia.1252
     ESP  Spanish_Spain.1252
     ESR  Spanish_Peru.1252
     ESS  Spanish_Argentina.1252
     ESU  Spanish_Puerto Rico.1252
     ESV  Spanish_Venezuela.1252
     ESY  Spanish_Uruguay.1252
     ESZ  Spanish_Paraguay.1252
     ETI  Estonian_Estonia.1257
     EUQ  Basque_Spain.1252
     FAR  Farsi_Iran.1256
     FIN  Finnish_Finland.1252
     FOS  Faroese_Faroe Islands.1252
     FPO  Filipino_Philippines.1252
     FRA  French_France.1252
     FRB  French_Belgium.1252
     FRC  French_Canada.1252
     FRL  French_Luxembourg.1252
     FRM  French_Principality of Monaco.1252
     FRS  French_Switzerland.1252
     FYN  Frisian_Netherlands.1252
     GLC  Galician_Spain.1252
     HEB  Hebrew_Israel.1255
     HRB  Croatian_Bosnia and Herzegovina.1250
     HRV  Croatian_Croatia.1250
     HUN  Hungarian_Hungary.1250
     IND  Indonesian_Indonesia.1252
     IRE  Irish_Ireland.1252
     ISL  Icelandic_Iceland.1252
     ITA  Italian_Italy.1252
     ITS  Italian_Switzerland.1252
     IUK  Inuktitut (Latin)_Canada.1252
     JPN  Japanese_Japan.932
     KKZ  Kazakh_Kazakhstan.1251
     KOR  Korean_Korea.949
     KYR  Kyrgyz_Kyrgyzstan.1251
     LBX  Luxembourgish_Luxembourg.1252
     LTH  Lithuanian_Lithuania.1257
     LVI  Latvian_Latvia.1257
     MKI  FYRO Macedonian_Former Yugoslav Republic of Macedonia.1251
     MON  Mongolian_Mongolia.1251
     MPD  Mapudungun_Chile.1252
     MSB  Malay_Brunei Darussalam.1252
     MSL  Malay_Malaysia.1252
     MWK  Mohawk_Canada.1252
     NLB  Dutch_Belgium.1252
     NLD  Dutch_Netherlands.1252
     NON  Norwegian-Nynorsk_Norway.1252
     NOR  Norwegian (Bokmål)_Norway.1252
     NSO  Northern Sotho_South Africa.1252
     PLK  Polish_Poland.1250
     PTB  Portuguese_Brazil.1252
     PTG  Portuguese_Portugal.1252
     QUB  Quechua_Bolivia.1252
     QUE  Quechua_Ecuador.1252
     QUP  Quechua_Peru.1252
     RMC  Romansh_Switzerland.1252
     ROM  Romanian_Romania.1250
     RUS  Russian_Russia.1251
     SKY  Slovak_Slovakia.1250
     SLV  Slovenian_Slovenia.1250
     SMA  Sami (Southern)_Norway.1252
     SMB  Sami (Southern)_Sweden.1252
     SME  Sami (Northern)_Norway.1252
     SMF  Sami (Northern)_Sweden.1252
     SMG  Sami (Northern)_Finland.1252
     SMJ  Sami (Lule)_Norway.1252
     SMK  Sami (Lule)_Sweden.1252
     SMN  Sami (Inari)_Finland.1252
     SMS  Sami (Skolt)_Finland.1252
     SQI  Albanian_Albania.1250
     SRB  Serbian (Cyrillic)_Serbia and Montenegro.1251
     SRL  Serbian (Latin)_Serbia and Montenegro.1250
     SRN  Serbian (Cyrillic)_Bosnia and Herzegovina.1251
     SRS  Serbian (Latin)_Bosnia and Herzegovina.1250
     SVE  Swedish_Sweden.1252
     SVF  Swedish_Finland.1252
     SWK  Swahili_Kenya.1252
     THA  Thai_Thailand.874
     TRK  Turkish_Turkey.1254
     TSN  Tswana_South Africa.1252
     TTT  Tatar_Russia.1251
     UKR  Ukrainian_Ukraine.1251
     URD  Urdu_Islamic Republic of Pakistan.1256
     USA  English_United States.1252
     UZB  Uzbek (Latin)_Uzbekistan.1254
     VIT  Vietnamese_Viet Nam.1258
     XHO  Xhosa_South Africa.1252
     ZHH  Chinese_Hong Kong S.A.R..950
     ZHI  Chinese_Singapore.936
     ZHM  Chinese_Macau S.A.R..950
     ZUL  Zulu_South Africa.1252
 */

/* Table from ISO 639 language code, optionally with country or script suffix,
   to English name.
   Keep in sync with the gl_locale_name_from_win32_LANGID function in
   localename.c!  */
struct table_entry
{
  const char *code;
  const char *english;
};
static const struct table_entry language_table[] =
  {
    { "af", "Afrikaans" },
    { "am", "Amharic" },
    { "ar", "Arabic" },
    { "arn", "Mapudungun" },
    { "as", "Assamese" },
    { "az@cyrillic", "Azeri (Cyrillic)" },
    { "az@latin", "Azeri (Latin)" },
    { "ba", "Bashkir" },
    { "be", "Belarusian" },
    { "ber", "Tamazight" },
    { "ber@arabic", "Tamazight (Arabic)" },
    { "ber@latin", "Tamazight (Latin)" },
    { "bg", "Bulgarian" },
    { "bin", "Edo" },
    { "bn", "Bengali" },
    { "bn_BD", "Bengali (Bangladesh)" },
    { "bn_IN", "Bengali (India)" },
    { "bnt", "Sutu" },
    { "bo", "Tibetan" },
    { "br", "Breton" },
    { "bs", "BSB" }, /* "Bosnian (Latin)" */
    { "bs@cyrillic", "BSC" }, /* Bosnian (Cyrillic) */
    { "ca", "Catalan" },
    { "chr", "Cherokee" },
    { "co", "Corsican" },
    { "cpe", "Hawaiian" },
    { "cs", "Czech" },
    { "cy", "Welsh" },
    { "da", "Danish" },
    { "de", "German" },
    { "dsb", "Lower Sorbian" },
    { "dv", "Divehi" },
    { "el", "Greek" },
    { "en", "English" },
    { "es", "Spanish" },
    { "et", "Estonian" },
    { "eu", "Basque" },
    { "fa", "Farsi" },
    { "ff", "Fulfulde" },
    { "fi", "Finnish" },
    { "fo", "Faroese" }, /* "Faeroese" does not work */
    { "fr", "French" },
    { "fy", "Frisian" },
    { "ga", "IRE" }, /* Gaelic (Ireland) */
    { "gd", "Gaelic (Scotland)" },
    { "gd", "Scottish Gaelic" },
    { "gl", "Galician" },
    { "gn", "Guarani" },
    { "gsw", "Alsatian" },
    { "gu", "Gujarati" },
    { "ha", "Hausa" },
    { "he", "Hebrew" },
    { "hi", "Hindi" },
    { "hr", "Croatian" },
    { "hsb", "Upper Sorbian" },
    { "hu", "Hungarian" },
    { "hy", "Armenian" },
    { "id", "Indonesian" },
    { "ig", "Igbo" },
    { "ii", "Yi" },
    { "is", "Icelandic" },
    { "it", "Italian" },
    { "iu", "IUK" }, /* Inuktitut */
    { "ja", "Japanese" },
    { "ka", "Georgian" },
    { "kk", "Kazakh" },
    { "kl", "Greenlandic" },
    { "km", "Cambodian" },
    { "km", "Khmer" },
    { "kn", "Kannada" },
    { "ko", "Korean" },
    { "kok", "Konkani" },
    { "kr", "Kanuri" },
    { "ks", "Kashmiri" },
    { "ks_IN", "Kashmiri_India" },
    { "ks_PK", "Kashmiri (Arabic)_Pakistan" },
    { "ky", "Kyrgyz" },
    { "la", "Latin" },
    { "lb", "Luxembourgish" },
    { "lo", "Lao" },
    { "lt", "Lithuanian" },
    { "lv", "Latvian" },
    { "mi", "Maori" },
    { "mk", "FYRO Macedonian" },
    { "mk", "Macedonian" },
    { "ml", "Malayalam" },
    { "mn", "Mongolian" },
    { "mni", "Manipuri" },
    { "moh", "Mohawk" },
    { "mr", "Marathi" },
    { "ms", "Malay" },
    { "mt", "Maltese" },
    { "my", "Burmese" },
    { "nb", "NOR" }, /* Norwegian Bokmål */
    { "ne", "Nepali" },
    { "nic", "Ibibio" },
    { "nl", "Dutch" },
    { "nn", "NON" }, /* Norwegian Nynorsk */
    { "no", "Norwegian" },
    { "nso", "Northern Sotho" },
    { "nso", "Sepedi" },
    { "oc", "Occitan" },
    { "om", "Oromo" },
    { "or", "Oriya" },
    { "pa", "Punjabi" },
    { "pap", "Papiamentu" },
    { "pl", "Polish" },
    { "prs", "Dari" },
    { "ps", "Pashto" },
    { "pt", "Portuguese" },
    { "qu", "Quechua" },
    { "qut", "K'iche'" },
    { "rm", "Romansh" },
    { "ro", "Romanian" },
    { "ru", "Russian" },
    { "rw", "Kinyarwanda" },
    { "sa", "Sanskrit" },
    { "sah", "Yakut" },
    { "sd", "Sindhi" },
    { "se", "Sami (Northern)" },
    { "se", "Northern Sami" },
    { "si", "Sinhalese" },
    { "sk", "Slovak" },
    { "sl", "Slovenian" },
    { "sma", "Sami (Southern)" },
    { "sma", "Southern Sami" },
    { "smj", "Sami (Lule)" },
    { "smj", "Lule Sami" },
    { "smn", "Sami (Inari)" },
    { "smn", "Inari Sami" },
    { "sms", "Sami (Skolt)" },
    { "sms", "Skolt Sami" },
    { "so", "Somali" },
    { "sq", "Albanian" },
    { "sr", "Serbian (Latin)" },
    { "sr@cyrillic", "SRB" }, /* Serbian (Cyrillic) */
    { "sw", "Swahili" },
    { "syr", "Syriac" },
    { "ta", "Tamil" },
    { "te", "Telugu" },
    { "tg", "Tajik" },
    { "th", "Thai" },
    { "ti", "Tigrinya" },
    { "tk", "Turkmen" },
    { "tl", "Filipino" },
    { "tn", "Tswana" },
    { "tr", "Turkish" },
    { "ts", "Tsonga" },
    { "tt", "Tatar" },
    { "ug", "Uighur" },
    { "uk", "Ukrainian" },
    { "ur", "Urdu" },
    { "uz", "Uzbek" },
    { "uz", "Uzbek (Latin)" },
    { "uz@cyrillic", "Uzbek (Cyrillic)" },
    { "ve", "Venda" },
    { "vi", "Vietnamese" },
    { "wen", "Sorbian" },
    { "wo", "Wolof" },
    { "xh", "Xhosa" },
    { "yi", "Yiddish" },
    { "yo", "Yoruba" },
    { "zh", "Chinese" },
    { "zu", "Zulu" }
  };

/* Table from ISO 3166 country code to English name.
   Keep in sync with the gl_locale_name_from_win32_LANGID function in
   localename.c!  */
static const struct table_entry country_table[] =
  {
    { "AE", "U.A.E." },
    { "AF", "Afghanistan" },
    { "AL", "Albania" },
    { "AM", "Armenia" },
    { "AN", "Netherlands Antilles" },
    { "AR", "Argentina" },
    { "AT", "Austria" },
    { "AU", "Australia" },
    { "AZ", "Azerbaijan" },
    { "BA", "Bosnia and Herzegovina" },
    { "BD", "Bangladesh" },
    { "BE", "Belgium" },
    { "BG", "Bulgaria" },
    { "BH", "Bahrain" },
    { "BN", "Brunei Darussalam" },
    { "BO", "Bolivia" },
    { "BR", "Brazil" },
    { "BT", "Bhutan" },
    { "BY", "Belarus" },
    { "BZ", "Belize" },
    { "CA", "Canada" },
    { "CG", "Congo" },
    { "CH", "Switzerland" },
    { "CI", "Cote d'Ivoire" },
    { "CL", "Chile" },
    { "CM", "Cameroon" },
    { "CN", "People's Republic of China" },
    { "CO", "Colombia" },
    { "CR", "Costa Rica" },
    { "CS", "Serbia and Montenegro" },
    { "CZ", "Czech Republic" },
    { "DE", "Germany" },
    { "DK", "Denmark" },
    { "DO", "Dominican Republic" },
    { "DZ", "Algeria" },
    { "EC", "Ecuador" },
    { "EE", "Estonia" },
    { "EG", "Egypt" },
    { "ER", "Eritrea" },
    { "ES", "Spain" },
    { "ET", "Ethiopia" },
    { "FI", "Finland" },
    { "FO", "Faroe Islands" },
    { "FR", "France" },
    { "GB", "United Kingdom" },
    { "GD", "Caribbean" },
    { "GE", "Georgia" },
    { "GL", "Greenland" },
    { "GR", "Greece" },
    { "GT", "Guatemala" },
    { "HK", "Hong Kong" },
    { "HK", "Hong Kong S.A.R." },
    { "HN", "Honduras" },
    { "HR", "Croatia" },
    { "HT", "Haiti" },
    { "HU", "Hungary" },
    { "ID", "Indonesia" },
    { "IE", "Ireland" },
    { "IL", "Israel" },
    { "IN", "India" },
    { "IQ", "Iraq" },
    { "IR", "Iran" },
    { "IS", "Iceland" },
    { "IT", "Italy" },
    { "JM", "Jamaica" },
    { "JO", "Jordan" },
    { "JP", "Japan" },
    { "KE", "Kenya" },
    { "KG", "Kyrgyzstan" },
    { "KH", "Cambodia" },
    { "KR", "South Korea" },
    { "KW", "Kuwait" },
    { "KZ", "Kazakhstan" },
    { "LA", "Laos" },
    { "LB", "Lebanon" },
    { "LI", "Liechtenstein" },
    { "LK", "Sri Lanka" },
    { "LT", "Lithuania" },
    { "LU", "Luxembourg" },
    { "LV", "Latvia" },
    { "LY", "Libya" },
    { "MA", "Morocco" },
    { "MC", "Principality of Monaco" },
    { "MD", "Moldava" },
    { "MD", "Moldova" },
    { "ME", "Montenegro" },
    { "MK", "Former Yugoslav Republic of Macedonia" },
    { "ML", "Mali" },
    { "MM", "Myanmar" },
    { "MN", "Mongolia" },
    { "MO", "Macau S.A.R." },
    { "MT", "Malta" },
    { "MV", "Maldives" },
    { "MX", "Mexico" },
    { "MY", "Malaysia" },
    { "NG", "Nigeria" },
    { "NI", "Nicaragua" },
    { "NL", "Netherlands" },
    { "NO", "Norway" },
    { "NP", "Nepal" },
    { "NZ", "New Zealand" },
    { "OM", "Oman" },
    { "PA", "Panama" },
    { "PE", "Peru" },
    { "PH", "Philippines" },
    { "PK", "Islamic Republic of Pakistan" },
    { "PL", "Poland" },
    { "PR", "Puerto Rico" },
    { "PT", "Portugal" },
    { "PY", "Paraguay" },
    { "QA", "Qatar" },
    { "RE", "Reunion" },
    { "RO", "Romania" },
    { "RS", "Serbia" },
    { "RU", "Russia" },
    { "RW", "Rwanda" },
    { "SA", "Saudi Arabia" },
    { "SE", "Sweden" },
    { "SG", "Singapore" },
    { "SI", "Slovenia" },
    { "SK", "Slovak" },
    { "SN", "Senegal" },
    { "SO", "Somalia" },
    { "SR", "Suriname" },
    { "SV", "El Salvador" },
    { "SY", "Syria" },
    { "TH", "Thailand" },
    { "TJ", "Tajikistan" },
    { "TM", "Turkmenistan" },
    { "TN", "Tunisia" },
    { "TR", "Turkey" },
    { "TT", "Trinidad and Tobago" },
    { "TW", "Taiwan" },
    { "TZ", "Tanzania" },
    { "UA", "Ukraine" },
    { "US", "United States" },
    { "UY", "Uruguay" },
    { "VA", "Vatican" },
    { "VE", "Venezuela" },
    { "VN", "Viet Nam" },
    { "YE", "Yemen" },
    { "ZA", "South Africa" },
    { "ZW", "Zimbabwe" }
  };

/* Given a string STRING, find the set of indices i such that TABLE[i].code is
   the given STRING.  It is a range [lo,hi-1].  */
typedef struct { size_t lo; size_t hi; } range_t;
static void
search (const struct table_entry *table, size_t table_size, const char *string,
        range_t *result)
{
  /* The table is sorted.  Perform a binary search.  */
  size_t hi = table_size;
  size_t lo = 0;
  while (lo < hi)
    {
      /* Invariant:
         for i < lo, strcmp (table[i].code, string) < 0,
         for i >= hi, strcmp (table[i].code, string) > 0.  */
      size_t mid = (hi + lo) >> 1; /* >= lo, < hi */
      int cmp = strcmp (table[mid].code, string);
      if (cmp < 0)
        lo = mid + 1;
      else if (cmp > 0)
        hi = mid;
      else
        {
          /* Found an i with
               strcmp (language_table[i].code, string) == 0.
             Find the entire interval of such i.  */
          {
            size_t i;

            for (i = mid; i > lo; )
              {
                i--;
                if (strcmp (table[i].code, string) < 0)
                  {
                    lo = i + 1;
                    break;
                  }
              }
          }
          {
            size_t i;

            for (i = mid; i < hi; i++)
              {
                if (strcmp (table[i].code, string) > 0)
                  {
                    hi = i;
                    break;
                  }
              }
          }
          /* The set of i with
               strcmp (language_table[i].code, string) == 0
             is the interval [lo, hi-1].  */
          break;
        }
    }
  result->lo = lo;
  result->hi = hi;
}

/* Like setlocale, but accept also locale names in the form ll or ll_CC,
   where ll is an ISO 639 language code and CC is an ISO 3166 country code.  */
static char *
setlocale_unixlike (int category, const char *locale)
{
  char *result;
  char llCC_buf[64];
  char ll_buf[64];
  char CC_buf[64];

  /* First, try setlocale with the original argument unchanged.  */
  result = setlocale (category, locale);
  if (result != NULL)
    return result;

  /* Otherwise, assume the argument is in the form
       language[_territory][.codeset][@modifier]
     and try to map it using the tables.  */
  if (strlen (locale) < sizeof (llCC_buf))
    {
      /* Second try: Remove the codeset part.  */
      {
        const char *p = locale;
        char *q = llCC_buf;

        /* Copy the part before the dot.  */
        for (; *p != '\0' && *p != '.'; p++, q++)
          *q = *p;
        if (*p == '.')
          /* Skip the part up to the '@', if any.  */
          for (; *p != '\0' && *p != '@'; p++)
            ;
        /* Copy the part starting with '@', if any.  */
        for (; *p != '\0'; p++, q++)
          *q = *p;
        *q = '\0';
      }
      /* llCC_buf now contains
           language[_territory][@modifier]
       */
      if (strcmp (llCC_buf, locale) != 0)
        {
          result = setlocale (category, llCC_buf);
          if (result != NULL)
            return result;
        }
      /* Look it up in language_table.  */
      {
        range_t range;
        size_t i;

        search (language_table,
                sizeof (language_table) / sizeof (language_table[0]),
                llCC_buf,
                &range);

        for (i = range.lo; i < range.hi; i++)
          {
            /* Try the replacement in language_table[i].  */
            result = setlocale (category, language_table[i].english);
            if (result != NULL)
              return result;
          }
      }
      /* Split language[_territory][@modifier]
         into  ll_buf = language[@modifier]
         and   CC_buf = territory
       */
      {
        const char *underscore = strchr (llCC_buf, '_');
        if (underscore != NULL)
          {
            const char *territory_start = underscore + 1;
            const char *territory_end = strchr (territory_start, '@');
            if (territory_end == NULL)
              territory_end = territory_start + strlen (territory_start);

            memcpy (ll_buf, llCC_buf, underscore - llCC_buf);
            strcpy (ll_buf + (underscore - llCC_buf), territory_end);

            memcpy (CC_buf, territory_start, territory_end - territory_start);
            CC_buf[territory_end - territory_start] = '\0';

            {
              /* Look up ll_buf in language_table
                 and CC_buf in country_table.  */
              range_t language_range;

              search (language_table,
                      sizeof (language_table) / sizeof (language_table[0]),
                      ll_buf,
                      &language_range);
              if (language_range.lo < language_range.hi)
                {
                  range_t country_range;

                  search (country_table,
                          sizeof (country_table) / sizeof (country_table[0]),
                          CC_buf,
                          &country_range);
                  if (country_range.lo < country_range.hi)
                    {
                      size_t i;
                      size_t j;

                      for (i = language_range.lo; i < language_range.hi; i++)
                        for (j = country_range.lo; j < country_range.hi; j++)
                          {
                            /* Concatenate the replacements.  */
                            const char *part1 = language_table[i].english;
                            size_t part1_len = strlen (part1);
                            const char *part2 = country_table[j].english;
                            size_t part2_len = strlen (part2) + 1;
                            char buf[64+64];

                            if (!(part1_len + 1 + part2_len <= sizeof (buf)))
                              abort ();
                            memcpy (buf, part1, part1_len);
                            buf[part1_len] = '_';
                            memcpy (buf + part1_len + 1, part2, part2_len);

                            /* Try the concatenated replacements.  */
                            result = setlocale (category, buf);
                            if (result != NULL)
                              return result;
                          }
                    }

                  /* Try omitting the country entirely.  This may set a locale
                     corresponding to the wrong country, but is better than
                     failing entirely.  */
                  {
                    size_t i;

                    for (i = language_range.lo; i < language_range.hi; i++)
                      {
                        /* Try only the language replacement.  */
                        result =
                          setlocale (category, language_table[i].english);
                        if (result != NULL)
                          return result;
                      }
                  }
                }
            }
          }
      }
    }

  /* Failed.  */
  return NULL;
}

# else
#  define setlocale_unixlike setlocale
# endif

# if LC_MESSAGES == 1729

/* The system does not store an LC_MESSAGES locale category.  Do it here.  */
static char lc_messages_name[64] = "C";

/* Like setlocale, but support also LC_MESSAGES.  */
static char *
setlocale_single (int category, const char *locale)
{
  if (category == LC_MESSAGES)
    {
      if (locale != NULL)
        {
          lc_messages_name[sizeof (lc_messages_name) - 1] = '\0';
          strncpy (lc_messages_name, locale, sizeof (lc_messages_name) - 1);
        }
      return lc_messages_name;
    }
  else
    return setlocale_unixlike (category, locale);
}

# else
#  define setlocale_single setlocale_unixlike
# endif

DLL_EXPORTED
char *
libintl_setlocale (int category, const char *locale)
{
  if (locale != NULL && locale[0] == '\0')
    {
      /* A request to the set the current locale to the default locale.  */
      if (category == LC_ALL)
        {
          /* Set LC_CTYPE first.  Then the other categories.  */
          static int const categories[] =
            {
              LC_NUMERIC,
              LC_TIME,
              LC_COLLATE,
              LC_MONETARY,
              LC_MESSAGES
            };
          char *saved_locale;
          const char *base_name;
          unsigned int i;

          /* Back up the old locale, in case one of the steps fails.  */
          saved_locale = setlocale (LC_ALL, NULL);
          if (saved_locale == NULL)
            return NULL;
          saved_locale = strdup (saved_locale);
          if (saved_locale == NULL)
            return NULL;

          /* Set LC_CTYPE category.  Set all other categories (except possibly
             LC_MESSAGES) to the same value in the same call; this is likely to
             save calls.  */
          base_name =
            gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE));
          if (base_name == NULL)
            base_name = gl_locale_name_default ();

          if (setlocale_unixlike (LC_ALL, base_name) == NULL)
            goto fail;
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
          /* On native Windows, setlocale(LC_ALL,...) may succeed but set the
             LC_CTYPE category to an invalid value ("C") when it does not
             support the specified encoding.  Report a failure instead.  */
          if (strchr (base_name, '.') != NULL
              && strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
            goto fail;
# endif

          for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++)
            {
              int cat = categories[i];
              const char *name;

              name = gl_locale_name_environ (cat, category_to_name (cat));
              if (name == NULL)
                name = gl_locale_name_default ();

              /* If name is the same as base_name, it has already been set
                 through the setlocale call before the loop.  */
              if (strcmp (name, base_name) != 0
# if LC_MESSAGES == 1729
                  || cat == LC_MESSAGES
# endif
                 )
                if (setlocale_single (cat, name) == NULL)
                  goto fail;
            }

          /* All steps were successful.  */
          ++_nl_msg_cat_cntr;
          free (saved_locale);
          return setlocale (LC_ALL, NULL);

        fail:
          if (saved_locale[0] != '\0') /* don't risk an endless recursion */
            setlocale (LC_ALL, saved_locale);
          free (saved_locale);
          return NULL;
        }
      else
        {
          char *result;
          const char *name =
            gl_locale_name_environ (category, category_to_name (category));
          if (name == NULL)
            name = gl_locale_name_default ();

          result = setlocale_single (category, name);
          if (result != NULL)
            ++_nl_msg_cat_cntr;
          return result;
        }
    }
  else
    {
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
      if (category == LC_ALL && locale != NULL && strchr (locale, '.') != NULL)
        {
          char *saved_locale;

          /* Back up the old locale.  */
          saved_locale = setlocale (LC_ALL, NULL);
          if (saved_locale == NULL)
            return NULL;
          saved_locale = strdup (saved_locale);
          if (saved_locale == NULL)
            return NULL;

          if (setlocale_unixlike (LC_ALL, locale) == NULL)
            {
              free (saved_locale);
              return NULL;
            }

          /* On native Windows, setlocale(LC_ALL,...) may succeed but set the
             LC_CTYPE category to an invalid value ("C") when it does not
             support the specified encoding.  Report a failure instead.  */
          if (strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
            {
              if (saved_locale[0] != '\0') /* don't risk an endless recursion */
                setlocale (LC_ALL, saved_locale);
              free (saved_locale);
              return NULL;
            }

          /* It was really successful.  */
          ++_nl_msg_cat_cntr;
          free (saved_locale);
          return setlocale (LC_ALL, NULL);
        }
      else
# endif
        {
          char *result = setlocale_single (category, locale);
          if (result != NULL)
            ++_nl_msg_cat_cntr;
          return result;
        }
    }
}

# if HAVE_NEWLOCALE

DLL_EXPORTED
locale_t
libintl_newlocale (int category_mask, const char *locale, locale_t base)
{
  if (category_mask != 0 && locale != NULL && locale[0] == '\0')
    {
      /* A request to construct a locale_t object that refers to the default
         locale.  */

      /* Set LC_CTYPE first.  Then the other categories.  */
      static struct { int cat; int mask; } const categories[] =
        {
          { LC_CTYPE,    LC_CTYPE_MASK },
          { LC_NUMERIC,  LC_NUMERIC_MASK },
          { LC_TIME,     LC_TIME_MASK },
          { LC_COLLATE,  LC_COLLATE_MASK },
          { LC_MONETARY, LC_MONETARY_MASK },
          { LC_MESSAGES, LC_MESSAGES_MASK }
        };

      locale_t orig_base = base;

      if ((LC_ALL_MASK & ~category_mask) == 0)
        {
          const char *base_name;
          unsigned int i;

          /* Set LC_CTYPE category.  Set all other categories (except possibly
             LC_MESSAGES) to the same value in the same call; this is likely to
             save calls.  */
          base_name =
            gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE));
          if (base_name == NULL)
            base_name = gl_locale_name_default ();

          base = newlocale (LC_ALL_MASK, base_name, base);
          if (base == NULL)
            return NULL;

          for (i = 1; i < sizeof (categories) / sizeof (categories[0]); i++)
            {
              int category = categories[i].cat;
              int category_mask = categories[i].mask;
              const char *name;

              name =
                gl_locale_name_environ (category, category_to_name (category));
              if (name == NULL)
                name = gl_locale_name_default ();

              /* If name is the same as base_name, it has already been set
                 through the setlocale call before the loop.  */
              if (strcmp (name, base_name) != 0)
                {
                  locale_t copy = newlocale (category_mask, name, base);
                  if (copy == NULL)
                    goto fail;
                  /* No need to call freelocale (base) if copy != base; the
                     newlocale function already takes care of doing it.  */
                  base = copy;
                }
            }
        }
      else
        {
          unsigned int i;

          for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++)
            {
              int cat_mask = categories[i].mask;

              if ((category_mask & cat_mask) != 0)
                {
                  int cat = categories[i].cat;
                  const char *name;
                  locale_t copy;

                  name = gl_locale_name_environ (cat, category_to_name (cat));
                  if (name == NULL)
                    name = gl_locale_name_default ();

                  copy = newlocale (cat_mask, name, base);
                  if (copy == NULL)
                    goto fail;
                  /* No need to call freelocale (base) if copy != base; the
                     newlocale function already takes care of doing it.  */
                  base = copy;
                }
            }
        }

      /* All steps were successful.  */
      return base;

    fail:
      if (base != NULL && orig_base == NULL)
        {
          int saved_errno = errno;
          freelocale (base);
          errno = saved_errno;
        }
      return NULL;
    }
  else
    return newlocale (category_mask, locale, base);
}

# endif

#endif

Youez - 2016 - github.com/yon3zu
LinuXploit