wstring.c 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987
  1. /* Copyright (C) 2002 Manuel Novoa III
  2. *
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Library General Public
  5. * License as published by the Free Software Foundation; either
  6. * version 2 of the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Library General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Library General Public
  14. * License along with this library; if not, write to the Free
  15. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. /* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
  18. *
  19. * Besides uClibc, I'm using this code in my libc for elks, which is
  20. * a 16-bit environment with a fairly limited compiler. It would make
  21. * things much easier for me if this file isn't modified unnecessarily.
  22. * In particular, please put any new or replacement functions somewhere
  23. * else, and modify the makefile to use your version instead.
  24. * Thanks. Manuel
  25. *
  26. * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
  27. /* Dec 20, 2002
  28. * Initial test implementation of strcoll, strxfrm, wcscoll, and wcsxfrm.
  29. * The code needs to be cleaned up a good bit, but I'd like to see people
  30. * test it out.
  31. *
  32. * Sep 11, 2003
  33. * Patch by Atsushi Nemoto <anemo@mba.ocn.ne.jp> to do arch-required
  34. * mapping of signal strings (alpha, mips, hppa, sparc).
  35. */
  36. #define _STDIO_UTILITY
  37. #define _GNU_SOURCE
  38. #include <string.h>
  39. #include <strings.h>
  40. #include <stdio.h>
  41. #include <limits.h>
  42. #include <ctype.h>
  43. #include <stdlib.h>
  44. #include <errno.h>
  45. #include <signal.h>
  46. #include <assert.h>
  47. #include <locale.h>
  48. #ifdef WANT_WIDE
  49. #include <wchar.h>
  50. #include <wctype.h>
  51. #include <bits/uClibc_uwchar.h>
  52. #define Wvoid wchar_t
  53. #define Wchar wchar_t
  54. #define Wuchar __uwchar_t
  55. #define Wint wchar_t
  56. #else
  57. #define Wvoid void
  58. #define Wchar char
  59. typedef unsigned char __string_uchar_t;
  60. #define Wuchar __string_uchar_t
  61. #define Wint int
  62. #endif
  63. /**********************************************************************/
  64. /* NOTE: If we ever do internationalized syserr messages, this will
  65. * have to be changed! */
  66. #define _SYS_NERR 125
  67. #if defined(__mips__) || defined(__sparc__)
  68. /* sparce and mips have an extra error entry, as EDEADLK and EDEADLOCK have
  69. * different meanings on those platforms. */
  70. #undef _SYS_NERR
  71. #define _SYS_NERR 126
  72. #endif
  73. #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
  74. #define _SYS_ERRMSG_MAXLEN 50
  75. #else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  76. #define _SYS_ERRMSG_MAXLEN 0
  77. #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  78. extern const char _string_syserrmsgs[];
  79. #define _SYS_NSIG 32
  80. #ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__
  81. #define _SYS_SIGMSG_MAXLEN 25
  82. #else /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
  83. #define _SYS_SIGMSG_MAXLEN 0
  84. #endif /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
  85. extern const char _string_syssigmsgs[];
  86. #if _SYS_ERRMSG_MAXLEN < __UIM_BUFLEN_INT + 14
  87. #define _STRERROR_BUFSIZE (__UIM_BUFLEN_INT + 14)
  88. #else
  89. #define _STRERROR_BUFSIZE _SYS_ERRMSG_MAXLEN
  90. #endif
  91. #if _SYS_SIGMSG_MAXLEN < __UIM_BUFLEN_INT + 15
  92. #define _STRSIGNAL_BUFSIZE (__UIM_BUFLEN_INT + 15)
  93. #else
  94. #define _STRSIGNAL_BUFSIZE _SYS_SIGMSG_MAXLEN
  95. #endif
  96. /**********************************************************************/
  97. #if defined(L__string_syserrmsgs) && defined(__UCLIBC_HAS_ERRNO_MESSAGES__)
  98. const char _string_syserrmsgs[] = {
  99. /* 0: 0, 8 */ "Success\0"
  100. /* 1: 8, 24 */ "Operation not permitted\0"
  101. /* 2: 32, 26 */ "No such file or directory\0"
  102. /* 3: 58, 16 */ "No such process\0"
  103. /* 4: 74, 24 */ "Interrupted system call\0"
  104. /* 5: 98, 19 */ "Input/output error\0"
  105. /* 6: 117, 26 */ "No such device or address\0"
  106. /* 7: 143, 23 */ "Argument list too long\0"
  107. /* 8: 166, 18 */ "Exec format error\0"
  108. /* 9: 184, 20 */ "Bad file descriptor\0"
  109. /* 10: 204, 19 */ "No child processes\0"
  110. /* 11: 223, 33 */ "Resource temporarily unavailable\0"
  111. /* 12: 256, 23 */ "Cannot allocate memory\0"
  112. /* 13: 279, 18 */ "Permission denied\0"
  113. /* 14: 297, 12 */ "Bad address\0"
  114. /* 15: 309, 22 */ "Block device required\0"
  115. /* 16: 331, 24 */ "Device or resource busy\0"
  116. /* 17: 355, 12 */ "File exists\0"
  117. /* 18: 367, 26 */ "Invalid cross-device link\0"
  118. /* 19: 393, 15 */ "No such device\0"
  119. /* 20: 408, 16 */ "Not a directory\0"
  120. /* 21: 424, 15 */ "Is a directory\0"
  121. /* 22: 439, 17 */ "Invalid argument\0"
  122. /* 23: 456, 30 */ "Too many open files in system\0"
  123. /* 24: 486, 20 */ "Too many open files\0"
  124. /* 25: 506, 31 */ "Inappropriate ioctl for device\0"
  125. /* 26: 537, 15 */ "Text file busy\0"
  126. /* 27: 552, 15 */ "File too large\0"
  127. /* 28: 567, 24 */ "No space left on device\0"
  128. /* 29: 591, 13 */ "Illegal seek\0"
  129. /* 30: 604, 22 */ "Read-only file system\0"
  130. /* 31: 626, 15 */ "Too many links\0"
  131. /* 32: 641, 12 */ "Broken pipe\0"
  132. /* 33: 653, 33 */ "Numerical argument out of domain\0"
  133. /* 34: 686, 30 */ "Numerical result out of range\0"
  134. /* 35: 716, 26 */ "Resource deadlock avoided\0"
  135. /* 36: 742, 19 */ "File name too long\0"
  136. /* 37: 761, 19 */ "No locks available\0"
  137. /* 38: 780, 25 */ "Function not implemented\0"
  138. /* 39: 805, 20 */ "Directory not empty\0"
  139. /* 40: 825, 34 */ "Too many levels of symbolic links\0"
  140. /* 41: 859, 1 */ "\0"
  141. /* 42: 860, 27 */ "No message of desired type\0"
  142. /* 43: 887, 19 */ "Identifier removed\0"
  143. /* 44: 906, 28 */ "Channel number out of range\0"
  144. /* 45: 934, 25 */ "Level 2 not synchronized\0"
  145. /* 46: 959, 15 */ "Level 3 halted\0"
  146. /* 47: 974, 14 */ "Level 3 reset\0"
  147. /* 48: 988, 25 */ "Link number out of range\0"
  148. /* 49: 1013, 29 */ "Protocol driver not attached\0"
  149. /* 50: 1042, 27 */ "No CSI structure available\0"
  150. /* 51: 1069, 15 */ "Level 2 halted\0"
  151. /* 52: 1084, 17 */ "Invalid exchange\0"
  152. /* 53: 1101, 27 */ "Invalid request descriptor\0"
  153. /* 54: 1128, 14 */ "Exchange full\0"
  154. /* 55: 1142, 9 */ "No anode\0"
  155. /* 56: 1151, 21 */ "Invalid request code\0"
  156. /* 57: 1172, 13 */ "Invalid slot\0"
  157. /* 58: 1185, 1 */ "\0"
  158. /* 59: 1186, 21 */ "Bad font file format\0"
  159. /* 60: 1207, 20 */ "Device not a stream\0"
  160. /* 61: 1227, 18 */ "No data available\0"
  161. /* 62: 1245, 14 */ "Timer expired\0"
  162. /* 63: 1259, 25 */ "Out of streams resources\0"
  163. /* 64: 1284, 30 */ "Machine is not on the network\0"
  164. /* 65: 1314, 22 */ "Package not installed\0"
  165. /* 66: 1336, 17 */ "Object is remote\0"
  166. /* 67: 1353, 22 */ "Link has been severed\0"
  167. /* 68: 1375, 16 */ "Advertise error\0"
  168. /* 69: 1391, 14 */ "Srmount error\0"
  169. /* 70: 1405, 28 */ "Communication error on send\0"
  170. /* 71: 1433, 15 */ "Protocol error\0"
  171. /* 72: 1448, 19 */ "Multihop attempted\0"
  172. /* 73: 1467, 19 */ "RFS specific error\0"
  173. /* 74: 1486, 12 */ "Bad message\0"
  174. /* 75: 1498, 38 */ "Value too large for defined data type\0"
  175. /* 76: 1536, 27 */ "Name not unique on network\0"
  176. /* 77: 1563, 29 */ "File descriptor in bad state\0"
  177. /* 78: 1592, 23 */ "Remote address changed\0"
  178. /* 79: 1615, 39 */ "Can not access a needed shared library\0"
  179. /* 80: 1654, 37 */ "Accessing a corrupted shared library\0"
  180. /* 81: 1691, 32 */ ".lib section in a.out corrupted\0"
  181. /* 82: 1723, 48 */ "Attempting to link in too many shared libraries\0"
  182. /* 83: 1771, 38 */ "Cannot exec a shared library directly\0"
  183. /* 84: 1809, 50 */ "Invalid or incomplete multibyte or wide character\0"
  184. /* 85: 1859, 44 */ "Interrupted system call should be restarted\0"
  185. /* 86: 1903, 19 */ "Streams pipe error\0"
  186. /* 87: 1922, 15 */ "Too many users\0"
  187. /* 88: 1937, 31 */ "Socket operation on non-socket\0"
  188. /* 89: 1968, 29 */ "Destination address required\0"
  189. /* 90: 1997, 17 */ "Message too long\0"
  190. /* 91: 2014, 31 */ "Protocol wrong type for socket\0"
  191. /* 92: 2045, 23 */ "Protocol not available\0"
  192. /* 93: 2068, 23 */ "Protocol not supported\0"
  193. /* 94: 2091, 26 */ "Socket type not supported\0"
  194. /* 95: 2117, 24 */ "Operation not supported\0"
  195. /* 96: 2141, 30 */ "Protocol family not supported\0"
  196. /* 97: 2171, 41 */ "Address family not supported by protocol\0"
  197. /* 98: 2212, 23 */ "Address already in use\0"
  198. /* 99: 2235, 32 */ "Cannot assign requested address\0"
  199. /* 100: 2267, 16 */ "Network is down\0"
  200. /* 101: 2283, 23 */ "Network is unreachable\0"
  201. /* 102: 2306, 36 */ "Network dropped connection on reset\0"
  202. /* 103: 2342, 33 */ "Software caused connection abort\0"
  203. /* 104: 2375, 25 */ "Connection reset by peer\0"
  204. /* 105: 2400, 26 */ "No buffer space available\0"
  205. /* 106: 2426, 40 */ "Transport endpoint is already connected\0"
  206. /* 107: 2466, 36 */ "Transport endpoint is not connected\0"
  207. /* 108: 2502, 46 */ "Cannot send after transport endpoint shutdown\0"
  208. /* 109: 2548, 35 */ "Too many references: cannot splice\0"
  209. /* 110: 2583, 21 */ "Connection timed out\0"
  210. /* 111: 2604, 19 */ "Connection refused\0"
  211. /* 112: 2623, 13 */ "Host is down\0"
  212. /* 113: 2636, 17 */ "No route to host\0"
  213. /* 114: 2653, 30 */ "Operation already in progress\0"
  214. /* 115: 2683, 26 */ "Operation now in progress\0"
  215. /* 116: 2709, 22 */ "Stale NFS file handle\0"
  216. /* 117: 2731, 25 */ "Structure needs cleaning\0"
  217. /* 118: 2756, 28 */ "Not a XENIX named type file\0"
  218. /* 119: 2784, 30 */ "No XENIX semaphores available\0"
  219. /* 120: 2814, 21 */ "Is a named type file\0"
  220. /* 121: 2835, 17 */ "Remote I/O error\0"
  221. /* 122: 2852, 20 */ "Disk quota exceeded\0"
  222. /* 123: 2872, 16 */ "No medium found\0"
  223. /* 124: 2888, 18 */ "Wrong medium type"
  224. #if defined(__mips__) || defined(__sparc__)
  225. "\0"
  226. /* 125: 2906, 28 */ "File locking deadlock error"
  227. #endif
  228. /* Note: for mips we are ignoring ECANCELED since glibc doesn't have a
  229. * corresponsding message.*/
  230. };
  231. #endif
  232. /**********************************************************************/
  233. #if defined(L_sys_errlist) && defined(__UCLIBC_HAS_SYS_ERRLIST__)
  234. link_warning(_sys_errlist, "sys_nerr and sys_errlist are obsolete and uClibc support for them (in at least some configurations) will probably be unavailable in the near future.")
  235. const char *const sys_errlist[] = {
  236. [0] = _string_syserrmsgs + 0,
  237. [EPERM] = _string_syserrmsgs + 8,
  238. [ENOENT] = _string_syserrmsgs + 32,
  239. [ESRCH] = _string_syserrmsgs + 58,
  240. [EINTR] = _string_syserrmsgs + 74,
  241. [EIO] = _string_syserrmsgs + 98,
  242. [ENXIO] = _string_syserrmsgs + 117,
  243. [E2BIG] = _string_syserrmsgs + 143,
  244. [ENOEXEC] = _string_syserrmsgs + 166,
  245. [EBADF] = _string_syserrmsgs + 184,
  246. [ECHILD] = _string_syserrmsgs + 204,
  247. [EAGAIN] = _string_syserrmsgs + 223,
  248. [ENOMEM] = _string_syserrmsgs + 256,
  249. [EACCES] = _string_syserrmsgs + 279,
  250. [EFAULT] = _string_syserrmsgs + 297,
  251. [ENOTBLK] = _string_syserrmsgs + 309,
  252. [EBUSY] = _string_syserrmsgs + 331,
  253. [EEXIST] = _string_syserrmsgs + 355,
  254. [EXDEV] = _string_syserrmsgs + 367,
  255. [ENODEV] = _string_syserrmsgs + 393,
  256. [ENOTDIR] = _string_syserrmsgs + 408,
  257. [EISDIR] = _string_syserrmsgs + 424,
  258. [EINVAL] = _string_syserrmsgs + 439,
  259. [ENFILE] = _string_syserrmsgs + 456,
  260. [EMFILE] = _string_syserrmsgs + 486,
  261. [ENOTTY] = _string_syserrmsgs + 506,
  262. [ETXTBSY] = _string_syserrmsgs + 537,
  263. [EFBIG] = _string_syserrmsgs + 552,
  264. [ENOSPC] = _string_syserrmsgs + 567,
  265. [ESPIPE] = _string_syserrmsgs + 591,
  266. [EROFS] = _string_syserrmsgs + 604,
  267. [EMLINK] = _string_syserrmsgs + 626,
  268. [EPIPE] = _string_syserrmsgs + 641,
  269. [EDOM] = _string_syserrmsgs + 653,
  270. [ERANGE] = _string_syserrmsgs + 686,
  271. [EDEADLK] = _string_syserrmsgs + 716,
  272. [ENAMETOOLONG] = _string_syserrmsgs + 742,
  273. [ENOLCK] = _string_syserrmsgs + 761,
  274. [ENOSYS] = _string_syserrmsgs + 780,
  275. [ENOTEMPTY] = _string_syserrmsgs + 805,
  276. [ELOOP] = _string_syserrmsgs + 825,
  277. /* _string_syserrmsgs + 859, */
  278. [ENOMSG] = _string_syserrmsgs + 860,
  279. [EIDRM] = _string_syserrmsgs + 887,
  280. [ECHRNG] = _string_syserrmsgs + 906,
  281. [EL2NSYNC] = _string_syserrmsgs + 934,
  282. [EL3HLT] = _string_syserrmsgs + 959,
  283. [EL3RST] = _string_syserrmsgs + 974,
  284. [ELNRNG] = _string_syserrmsgs + 988,
  285. [EUNATCH] = _string_syserrmsgs + 1013,
  286. [ENOCSI] = _string_syserrmsgs + 1042,
  287. [EL2HLT] = _string_syserrmsgs + 1069,
  288. [EBADE] = _string_syserrmsgs + 1084,
  289. [EBADR] = _string_syserrmsgs + 1101,
  290. [EXFULL] = _string_syserrmsgs + 1128,
  291. [ENOANO] = _string_syserrmsgs + 1142,
  292. [EBADRQC] = _string_syserrmsgs + 1151,
  293. [EBADSLT] = _string_syserrmsgs + 1172,
  294. /* _string_syserrmsgs + 1185, */
  295. [EBFONT] = _string_syserrmsgs + 1186,
  296. [ENOSTR] = _string_syserrmsgs + 1207,
  297. [ENODATA] = _string_syserrmsgs + 1227,
  298. [ETIME] = _string_syserrmsgs + 1245,
  299. [ENOSR] = _string_syserrmsgs + 1259,
  300. [ENONET] = _string_syserrmsgs + 1284,
  301. [ENOPKG] = _string_syserrmsgs + 1314,
  302. [EREMOTE] = _string_syserrmsgs + 1336,
  303. [ENOLINK] = _string_syserrmsgs + 1353,
  304. [EADV] = _string_syserrmsgs + 1375,
  305. [ESRMNT] = _string_syserrmsgs + 1391,
  306. [ECOMM] = _string_syserrmsgs + 1405,
  307. [EPROTO] = _string_syserrmsgs + 1433,
  308. [EMULTIHOP] = _string_syserrmsgs + 1448,
  309. [EDOTDOT] = _string_syserrmsgs + 1467,
  310. [EBADMSG] = _string_syserrmsgs + 1486,
  311. [EOVERFLOW] = _string_syserrmsgs + 1498,
  312. [ENOTUNIQ] = _string_syserrmsgs + 1536,
  313. [EBADFD] = _string_syserrmsgs + 1563,
  314. [EREMCHG] = _string_syserrmsgs + 1592,
  315. [ELIBACC] = _string_syserrmsgs + 1615,
  316. [ELIBBAD] = _string_syserrmsgs + 1654,
  317. [ELIBSCN] = _string_syserrmsgs + 1691,
  318. [ELIBMAX] = _string_syserrmsgs + 1723,
  319. [ELIBEXEC] = _string_syserrmsgs + 1771,
  320. [EILSEQ] = _string_syserrmsgs + 1809,
  321. [ERESTART] = _string_syserrmsgs + 1859,
  322. [ESTRPIPE] = _string_syserrmsgs + 1903,
  323. [EUSERS] = _string_syserrmsgs + 1922,
  324. [ENOTSOCK] = _string_syserrmsgs + 1937,
  325. [EDESTADDRREQ] = _string_syserrmsgs + 1968,
  326. [EMSGSIZE] = _string_syserrmsgs + 1997,
  327. [EPROTOTYPE] = _string_syserrmsgs + 2014,
  328. [ENOPROTOOPT] = _string_syserrmsgs + 2045,
  329. [EPROTONOSUPPORT] = _string_syserrmsgs + 2068,
  330. [ESOCKTNOSUPPORT] = _string_syserrmsgs + 2091,
  331. [EOPNOTSUPP] = _string_syserrmsgs + 2117,
  332. [EPFNOSUPPORT] = _string_syserrmsgs + 2141,
  333. [EAFNOSUPPORT] = _string_syserrmsgs + 2171,
  334. [EADDRINUSE] = _string_syserrmsgs + 2212,
  335. [EADDRNOTAVAIL] = _string_syserrmsgs + 2235,
  336. [ENETDOWN] = _string_syserrmsgs + 2267,
  337. [ENETUNREACH] = _string_syserrmsgs + 2283,
  338. [ENETRESET] = _string_syserrmsgs + 2306,
  339. [ECONNABORTED] = _string_syserrmsgs + 2342,
  340. [ECONNRESET] = _string_syserrmsgs + 2375,
  341. [ENOBUFS] = _string_syserrmsgs + 2400,
  342. [EISCONN] = _string_syserrmsgs + 2426,
  343. [ENOTCONN] = _string_syserrmsgs + 2466,
  344. [ESHUTDOWN] = _string_syserrmsgs + 2502,
  345. [ETOOMANYREFS] = _string_syserrmsgs + 2548,
  346. [ETIMEDOUT] = _string_syserrmsgs + 2583,
  347. [ECONNREFUSED] = _string_syserrmsgs + 2604,
  348. [EHOSTDOWN] = _string_syserrmsgs + 2623,
  349. [EHOSTUNREACH] = _string_syserrmsgs + 2636,
  350. [EALREADY] = _string_syserrmsgs + 2653,
  351. [EINPROGRESS] = _string_syserrmsgs + 2683,
  352. [ESTALE] = _string_syserrmsgs + 2709,
  353. [EUCLEAN] = _string_syserrmsgs + 2731,
  354. [ENOTNAM] = _string_syserrmsgs + 2756,
  355. [ENAVAIL] = _string_syserrmsgs + 2784,
  356. [EISNAM] = _string_syserrmsgs + 2814,
  357. [EREMOTEIO] = _string_syserrmsgs + 2835,
  358. [EDQUOT] = _string_syserrmsgs + 2852,
  359. [ENOMEDIUM] = _string_syserrmsgs + 2872,
  360. [EMEDIUMTYPE] = _string_syserrmsgs + 2888,
  361. #if EDEADLOCK != EDEADLK
  362. [EDEADLOCK] = _string_syserrmsgs + 2906,
  363. #endif
  364. #if EWOULDBLOCK != EAGAIN
  365. #error EWOULDBLOCK does not equal EAGAIN
  366. #endif
  367. /* For now, ignore the other arch-specific errors. glibc only maps EPROCLIM. */
  368. /* some other mips errors */
  369. #ifdef ECANCELED
  370. #endif
  371. #ifdef EINIT
  372. #endif
  373. #ifdef EREMDEV
  374. #endif
  375. /* some other sparc errors */
  376. #ifdef EPROCLIM
  377. #endif
  378. #ifdef ERREMOTE
  379. #endif
  380. };
  381. int sys_nerr = sizeof(sys_errlist)/sizeof(sys_errlist[0]);
  382. #endif
  383. /**********************************************************************/
  384. #ifdef L_wmemcpy
  385. #define L_memcpy
  386. #define Wmemcpy wmemcpy
  387. #else
  388. #define Wmemcpy memcpy
  389. #endif
  390. #ifdef L_memcpy
  391. Wvoid *Wmemcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
  392. {
  393. register Wchar *r1 = s1;
  394. register const Wchar *r2 = s2;
  395. #ifdef __BCC__
  396. while (n--) {
  397. *r1++ = *r2++;
  398. }
  399. #else
  400. while (n) {
  401. *r1++ = *r2++;
  402. --n;
  403. }
  404. #endif
  405. return s1;
  406. }
  407. #endif
  408. /**********************************************************************/
  409. #ifdef L_wmemmove
  410. #define L_memmove
  411. #define Wmemmove wmemmove
  412. #else
  413. #define Wmemmove memmove
  414. #endif
  415. #ifdef L_memmove
  416. Wvoid *Wmemmove(Wvoid *s1, const Wvoid *s2, size_t n)
  417. {
  418. #ifdef __BCC__
  419. register Wchar *s = (Wchar *) s1;
  420. register const Wchar *p = (const Wchar *) s2;
  421. if (p >= s) {
  422. while (n--) {
  423. *s++ = *p++;
  424. }
  425. } else {
  426. s += n;
  427. p += n;
  428. while (n--) {
  429. *--s = *--p;
  430. }
  431. }
  432. return s1;
  433. #else
  434. register Wchar *s = (Wchar *) s1;
  435. register const Wchar *p = (const Wchar *) s2;
  436. if (p >= s) {
  437. while (n) {
  438. *s++ = *p++;
  439. --n;
  440. }
  441. } else {
  442. while (n) {
  443. --n;
  444. s[n] = p[n];
  445. }
  446. }
  447. return s1;
  448. #endif
  449. }
  450. #endif
  451. /**********************************************************************/
  452. #ifdef L_wcscpy
  453. #define L_strcpy
  454. #define Wstrcpy wcscpy
  455. #else
  456. #define Wstrcpy strcpy
  457. #endif
  458. #ifdef L_strcpy
  459. Wchar *Wstrcpy(Wchar * __restrict s1, const Wchar * __restrict s2)
  460. {
  461. register Wchar *s = s1;
  462. #ifdef __BCC__
  463. do {
  464. *s = *s2++;
  465. } while (*s++ != 0);
  466. #else
  467. while ( (*s++ = *s2++) != 0 );
  468. #endif
  469. return s1;
  470. }
  471. #endif
  472. /**********************************************************************/
  473. #ifdef L_wcsncpy
  474. #define L_strncpy
  475. #define Wstrncpy wcsncpy
  476. #else
  477. #define Wstrncpy strncpy
  478. #endif
  479. #ifdef L_strncpy
  480. Wchar *Wstrncpy(Wchar * __restrict s1, register const Wchar * __restrict s2,
  481. size_t n)
  482. {
  483. register Wchar *s = s1;
  484. #ifdef __BCC__
  485. while (n--) {
  486. if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
  487. ++s;
  488. }
  489. #else
  490. while (n) {
  491. if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
  492. ++s;
  493. --n;
  494. }
  495. #endif
  496. return s1;
  497. }
  498. #endif
  499. /**********************************************************************/
  500. #ifdef L_wcscat
  501. #define L_strcat
  502. #define Wstrcat wcscat
  503. #else
  504. #define Wstrcat strcat
  505. #endif
  506. #ifdef L_strcat
  507. Wchar *Wstrcat(Wchar * __restrict s1, register const Wchar * __restrict s2)
  508. {
  509. register Wchar *s = s1;
  510. while (*s++);
  511. --s;
  512. while ((*s++ = *s2++) != 0);
  513. return s1;
  514. }
  515. #endif
  516. /**********************************************************************/
  517. #ifdef L_wcsncat
  518. #define L_strncat
  519. #define Wstrncat wcsncat
  520. #else
  521. #define Wstrncat strncat
  522. #endif
  523. #ifdef L_strncat
  524. Wchar *Wstrncat(Wchar * __restrict s1, register const Wchar * __restrict s2,
  525. size_t n)
  526. {
  527. register Wchar *s = s1;
  528. while (*s++);
  529. --s;
  530. #if __BCC__
  531. while (n-- && ((*s = *s2++) != 0)) ++s;
  532. #else
  533. while (n && ((*s = *s2++) != 0)) {
  534. --n;
  535. ++s;
  536. }
  537. #endif
  538. *s = 0;
  539. return s1;
  540. }
  541. #endif
  542. /**********************************************************************/
  543. #ifdef L_wmemcmp
  544. #define L_memcmp
  545. #define Wmemcmp wmemcmp
  546. #else
  547. #define Wmemcmp memcmp
  548. #endif
  549. #ifdef L_memcmp
  550. #ifndef L_wmemcmp
  551. weak_alias(memcmp,bcmp);
  552. #endif
  553. int Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n)
  554. {
  555. register const Wuchar *r1 = (const Wuchar *) s1;
  556. register const Wuchar *r2 = (const Wuchar *) s2;
  557. #ifdef WANT_WIDE
  558. while (n && (*r1 == *r2)) {
  559. ++r1;
  560. ++r2;
  561. --n;
  562. }
  563. return (n == 0) ? 0 : ((*r1 < *r2) ? -1 : 1);
  564. #else
  565. int r = 0;
  566. while (n-- && ((r = ((int)(*r1++)) - *r2++) == 0));
  567. return r;
  568. #endif
  569. }
  570. #endif
  571. /**********************************************************************/
  572. #ifdef L_wcscmp
  573. #define L_strcmp
  574. #define Wstrcmp wcscmp
  575. #else
  576. #define Wstrcmp strcmp
  577. #endif
  578. #ifdef L_strcmp
  579. #ifdef __LOCALE_C_ONLY
  580. #ifdef L_wcscmp
  581. weak_alias(wcscmp,wcscoll);
  582. #else /* L_wcscmp */
  583. weak_alias(strcmp,strcoll);
  584. #endif /* L_wcscmp */
  585. #endif /* __LOCALE_C_ONLY */
  586. int Wstrcmp(register const Wchar *s1, register const Wchar *s2)
  587. {
  588. #ifdef WANT_WIDE
  589. while (*((Wuchar *)s1) == *((Wuchar *)s2)) {
  590. if (!*s1++) {
  591. return 0;
  592. }
  593. ++s2;
  594. }
  595. return (*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1;
  596. #else
  597. int r;
  598. while (((r = ((int)(*((Wuchar *)s1))) - *((Wuchar *)s2++))
  599. == 0) && *s1++);
  600. return r;
  601. #endif
  602. }
  603. #endif
  604. /**********************************************************************/
  605. #ifdef L_wcsncmp
  606. #define L_strncmp
  607. #define Wstrncmp wcsncmp
  608. #else
  609. #define Wstrncmp strncmp
  610. #endif
  611. #ifdef L_strncmp
  612. int Wstrncmp(register const Wchar *s1, register const Wchar *s2, size_t n)
  613. {
  614. #ifdef WANT_WIDE
  615. while (n && (*((Wuchar *)s1) == *((Wuchar *)s2))) {
  616. if (!*s1++) {
  617. return 0;
  618. }
  619. ++s2;
  620. --n;
  621. }
  622. return (n == 0) ? 0 : ((*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1);
  623. #else
  624. int r = 0;
  625. while (n--
  626. && ((r = ((int)(*((unsigned char *)s1))) - *((unsigned char *)s2++))
  627. == 0)
  628. && *s1++);
  629. return r;
  630. #endif
  631. }
  632. #endif
  633. /**********************************************************************/
  634. #ifdef L_wmemchr
  635. #define L_memchr
  636. #define Wmemchr wmemchr
  637. #else
  638. #define Wmemchr memchr
  639. #endif
  640. #ifdef L_memchr
  641. Wvoid *Wmemchr(const Wvoid *s, Wint c, size_t n)
  642. {
  643. register const Wuchar *r = (const Wuchar *) s;
  644. #ifdef __BCC__
  645. /* bcc can optimize the counter if it thinks it is a pointer... */
  646. register const char *np = (const char *) n;
  647. #else
  648. #define np n
  649. #endif
  650. while (np) {
  651. if (*r == ((Wuchar)c)) {
  652. return (Wvoid *) r; /* silence the warning */
  653. }
  654. ++r;
  655. --np;
  656. }
  657. return NULL;
  658. }
  659. #undef np
  660. #endif
  661. /**********************************************************************/
  662. #ifdef L_wcschr
  663. #define L_strchr
  664. #define Wstrchr wcschr
  665. #else
  666. #define Wstrchr strchr
  667. #endif
  668. #ifdef L_strchr
  669. #ifndef L_wcschr
  670. weak_alias(strchr,index);
  671. #endif
  672. Wchar *Wstrchr(register const Wchar *s, Wint c)
  673. {
  674. do {
  675. if (*s == ((Wchar)c)) {
  676. return (Wchar *) s; /* silence the warning */
  677. }
  678. } while (*s++);
  679. return NULL;
  680. }
  681. #endif
  682. /**********************************************************************/
  683. #ifdef L_wcscspn
  684. #define L_strcspn
  685. #define Wstrcspn wcscspn
  686. #else
  687. #define Wstrcspn strcspn
  688. #endif
  689. #ifdef L_strcspn
  690. size_t Wstrcspn(const Wchar *s1, const Wchar *s2)
  691. {
  692. register const Wchar *s;
  693. register const Wchar *p;
  694. for ( s=s1 ; *s ; s++ ) {
  695. for ( p=s2 ; *p ; p++ ) {
  696. if (*p == *s) goto done;
  697. }
  698. }
  699. done:
  700. return s - s1;
  701. }
  702. #endif
  703. /**********************************************************************/
  704. #ifdef L_wcspbrk
  705. #define L_strpbrk
  706. #define Wstrpbrk wcspbrk
  707. #else
  708. #define Wstrpbrk strpbrk
  709. #endif
  710. #ifdef L_strpbrk
  711. Wchar *Wstrpbrk(const Wchar *s1, const Wchar *s2)
  712. {
  713. register const Wchar *s;
  714. register const Wchar *p;
  715. for ( s=s1 ; *s ; s++ ) {
  716. for ( p=s2 ; *p ; p++ ) {
  717. if (*p == *s) return (Wchar *) s; /* silence the warning */
  718. }
  719. }
  720. return NULL;
  721. }
  722. #endif
  723. /**********************************************************************/
  724. #ifdef L_wcsrchr
  725. #define L_strrchr
  726. #define Wstrrchr wcsrchr
  727. #else
  728. #define Wstrrchr strrchr
  729. #endif
  730. #ifdef L_strrchr
  731. #ifndef L_wcsrchr
  732. weak_alias(strrchr,rindex);
  733. #endif
  734. Wchar *Wstrrchr(register const Wchar *s, Wint c)
  735. {
  736. register const Wchar *p;
  737. p = NULL;
  738. do {
  739. if (*s == (Wchar) c) {
  740. p = s;
  741. }
  742. } while (*s++);
  743. return (Wchar *) p; /* silence the warning */
  744. }
  745. #endif
  746. /**********************************************************************/
  747. #ifdef L_wcsspn
  748. #define L_strspn
  749. #define Wstrspn wcsspn
  750. #else
  751. #define Wstrspn strspn
  752. #endif
  753. #ifdef L_strspn
  754. size_t Wstrspn(const Wchar *s1, const Wchar *s2)
  755. {
  756. register const Wchar *s = s1;
  757. register const Wchar *p = s2;
  758. while (*p) {
  759. if (*p++ == *s) {
  760. ++s;
  761. p = s2;
  762. }
  763. }
  764. return s - s1;
  765. }
  766. #endif
  767. /**********************************************************************/
  768. #ifdef L_wcsstr
  769. #define L_strstr
  770. #define Wstrstr wcsstr
  771. #else
  772. #define Wstrstr strstr
  773. #endif
  774. #ifdef L_strstr
  775. /* NOTE: This is the simple-minded O(len(s1) * len(s2)) worst-case approach. */
  776. #ifdef L_wcsstr
  777. weak_alias(wcsstr,wcswcs);
  778. #endif
  779. Wchar *Wstrstr(const Wchar *s1, const Wchar *s2)
  780. {
  781. register const Wchar *s = s1;
  782. register const Wchar *p = s2;
  783. do {
  784. if (!*p) {
  785. return (Wchar *) s1;;
  786. }
  787. if (*p == *s) {
  788. ++p;
  789. ++s;
  790. } else {
  791. p = s2;
  792. if (!*s) {
  793. return NULL;
  794. }
  795. s = ++s1;
  796. }
  797. } while (1);
  798. }
  799. #endif
  800. /**********************************************************************/
  801. #undef Wstrspn
  802. #undef Wstrpbrk
  803. #ifdef L_wcstok
  804. #define L_strtok_r
  805. #define Wstrtok_r wcstok
  806. #define Wstrspn wcsspn
  807. #define Wstrpbrk wcspbrk
  808. #else
  809. #define Wstrtok_r strtok_r
  810. #define Wstrspn strspn
  811. #define Wstrpbrk strpbrk
  812. #endif
  813. #ifdef L_strtok_r
  814. Wchar *Wstrtok_r(Wchar * __restrict s1, const Wchar * __restrict s2,
  815. Wchar ** __restrict next_start)
  816. {
  817. register Wchar *s;
  818. register Wchar *p;
  819. #if 1
  820. if (((s = s1) != NULL) || ((s = *next_start) != NULL)) {
  821. if (*(s += Wstrspn(s, s2))) {
  822. if ((p = Wstrpbrk(s, s2)) != NULL) {
  823. *p++ = 0;
  824. }
  825. } else {
  826. p = s = NULL;
  827. }
  828. *next_start = p;
  829. }
  830. return s;
  831. #else
  832. if (!(s = s1)) {
  833. s = *next_start;
  834. }
  835. if (s && *(s += Wstrspn(s, s2))) {
  836. if (*(p = s + Wstrcspn(s, s2))) {
  837. *p++ = 0;
  838. }
  839. *next_start = p;
  840. return s;
  841. }
  842. return NULL; /* TODO: set *next_start = NULL for safety? */
  843. #endif
  844. }
  845. #endif
  846. /**********************************************************************/
  847. /* #ifdef L_wcstok */
  848. /* #define L_strtok */
  849. /* #define Wstrtok wcstok */
  850. /* #define Wstrtok_r wcstok_r */
  851. /* #else */
  852. /* #define Wstrtok strtok */
  853. /* #define Wstrtok_r strtok_r */
  854. /* #endif */
  855. #ifdef L_strtok
  856. #define Wstrtok strtok
  857. #define Wstrtok_r strtok_r
  858. Wchar *Wstrtok(Wchar * __restrict s1, const Wchar * __restrict s2)
  859. {
  860. static Wchar *next_start; /* Initialized to 0 since in bss. */
  861. return Wstrtok_r(s1, s2, &next_start);
  862. }
  863. #endif
  864. /**********************************************************************/
  865. #ifdef L_wmemset
  866. #define L_memset
  867. #define Wmemset wmemset
  868. #else
  869. #define Wmemset memset
  870. #endif
  871. #ifdef L_memset
  872. Wvoid *Wmemset(Wvoid *s, Wint c, size_t n)
  873. {
  874. register Wuchar *p = (Wuchar *) s;
  875. #ifdef __BCC__
  876. /* bcc can optimize the counter if it thinks it is a pointer... */
  877. register const char *np = (const char *) n;
  878. #else
  879. #define np n
  880. #endif
  881. while (np) {
  882. *p++ = (Wuchar) c;
  883. --np;
  884. }
  885. return s;
  886. }
  887. #undef np
  888. #endif
  889. /**********************************************************************/
  890. #ifdef L_wcslen
  891. #define L_strlen
  892. #define Wstrlen wcslen
  893. #else
  894. #define Wstrlen strlen
  895. #endif
  896. #ifdef L_strlen
  897. size_t Wstrlen(const Wchar *s)
  898. {
  899. register const Wchar *p;
  900. for (p=s ; *p ; p++);
  901. return p - s;
  902. }
  903. #endif
  904. /**********************************************************************/
  905. /* ANSI/ISO end here */
  906. /**********************************************************************/
  907. #ifdef L_ffs
  908. int ffs(int i)
  909. {
  910. #if 1
  911. /* inlined binary search method */
  912. char n = 1;
  913. #if UINT_MAX == 0xffffU
  914. /* nothing to do here -- just trying to avoiding possible problems */
  915. #elif UINT_MAX == 0xffffffffU
  916. if (!(i & 0xffff)) {
  917. n += 16;
  918. i >>= 16;
  919. }
  920. #else
  921. #error ffs needs rewriting!
  922. #endif
  923. if (!(i & 0xff)) {
  924. n += 8;
  925. i >>= 8;
  926. }
  927. if (!(i & 0x0f)) {
  928. n += 4;
  929. i >>= 4;
  930. }
  931. if (!(i & 0x03)) {
  932. n += 2;
  933. i >>= 2;
  934. }
  935. return (i) ? (n + ((i+1) & 0x01)) : 0;
  936. #else
  937. /* linear search -- slow, but small */
  938. int n;
  939. for (n = 0 ; i ; ++n) {
  940. i >>= 1;
  941. }
  942. return n;
  943. #endif
  944. }
  945. #endif
  946. /**********************************************************************/
  947. #if defined(L_strcasecmp) || defined(L_strcasecmp_l) || defined(L_wcscasecmp) || defined(L_wcscasecmp_l)
  948. #if defined(L_wcscasecmp) || defined(L_wcscasecmp_l)
  949. #define strcasecmp wcscasecmp
  950. #define strcasecmp_l wcscasecmp_l
  951. #define __strcasecmp_l __wcscasecmp_l
  952. #ifdef __UCLIBC_DO_XLOCALE
  953. #define TOLOWER(C) __towlower_l((C), locale_arg)
  954. #else
  955. #define TOLOWER(C) towlower((C))
  956. #endif
  957. #else /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */
  958. #ifdef __UCLIBC_DO_XLOCALE
  959. #define TOLOWER(C) __tolower_l((C), locale_arg)
  960. #else
  961. #define TOLOWER(C) tolower((C))
  962. #endif
  963. #endif /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */
  964. #if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
  965. int strcasecmp(register const Wchar *s1, register const Wchar *s2)
  966. {
  967. return __strcasecmp_l(s1, s2, __UCLIBC_CURLOCALE);
  968. }
  969. #else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  970. int __XL(strcasecmp)(register const Wchar *s1, register const Wchar *s2
  971. __LOCALE_PARAM )
  972. {
  973. #ifdef WANT_WIDE
  974. while ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2))) {
  975. if (!*s1++) {
  976. return 0;
  977. }
  978. ++s2;
  979. }
  980. return (((Wuchar)TOLOWER(*s1)) < ((Wuchar)TOLOWER(*s2))) ? -1 : 1;
  981. /* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
  982. #else
  983. int r = 0;
  984. while ( ((s1 == s2) ||
  985. !(r = ((int)( TOLOWER(*((Wuchar *)s1))))
  986. - TOLOWER(*((Wuchar *)s2))))
  987. && (++s2, *s1++));
  988. return r;
  989. #endif
  990. }
  991. __XL_ALIAS(strcasecmp)
  992. #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  993. #endif
  994. /**********************************************************************/
  995. #if defined(L_strncasecmp) || defined(L_strncasecmp_l) || defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l)
  996. #if defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l)
  997. #define strncasecmp wcsncasecmp
  998. #define strncasecmp_l wcsncasecmp_l
  999. #define __strncasecmp_l __wcsncasecmp_l
  1000. #ifdef __UCLIBC_DO_XLOCALE
  1001. #define TOLOWER(C) __towlower_l((C), locale_arg)
  1002. #else
  1003. #define TOLOWER(C) towlower((C))
  1004. #endif
  1005. #else /* defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) */
  1006. #ifdef __UCLIBC_DO_XLOCALE
  1007. #define TOLOWER(C) __tolower_l((C), locale_arg)
  1008. #else
  1009. #define TOLOWER(C) tolower((C))
  1010. #endif
  1011. #endif /* defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) */
  1012. #if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
  1013. int strncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n)
  1014. {
  1015. return __strncasecmp_l(s1, s2, n, __UCLIBC_CURLOCALE);
  1016. }
  1017. #else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  1018. int __XL(strncasecmp)(register const Wchar *s1, register const Wchar *s2,
  1019. size_t n __LOCALE_PARAM )
  1020. {
  1021. #ifdef WANT_WIDE
  1022. while (n && ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2)))) {
  1023. if (!*s1++) {
  1024. return 0;
  1025. }
  1026. ++s2;
  1027. --n;
  1028. }
  1029. return (n == 0)
  1030. ? 0
  1031. : ((((Wuchar)TOLOWER(*s1)) < ((Wuchar)TOLOWER(*s2))) ? -1 : 1);
  1032. /* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
  1033. #else
  1034. int r = 0;
  1035. while ( n
  1036. && ((s1 == s2) ||
  1037. !(r = ((int)( TOLOWER(*((unsigned char *)s1))))
  1038. - TOLOWER(*((unsigned char *)s2))))
  1039. && (--n, ++s2, *s1++));
  1040. return r;
  1041. #endif
  1042. }
  1043. __XL_ALIAS(strncasecmp)
  1044. #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  1045. #endif
  1046. /**********************************************************************/
  1047. #ifdef L_wcsnlen
  1048. #define L_strnlen
  1049. #define Wstrnlen wcsnlen
  1050. #else
  1051. #define Wstrnlen strnlen
  1052. #endif
  1053. #ifdef L_strnlen
  1054. size_t Wstrnlen(const Wchar *s, size_t max)
  1055. {
  1056. register const Wchar *p = s;
  1057. #ifdef __BCC__
  1058. /* bcc can optimize the counter if it thinks it is a pointer... */
  1059. register const char *maxp = (const char *) max;
  1060. #else
  1061. #define maxp max
  1062. #endif
  1063. while (maxp && *p) {
  1064. ++p;
  1065. --maxp;
  1066. }
  1067. return p - s;
  1068. }
  1069. #undef maxp
  1070. #endif
  1071. /**********************************************************************/
  1072. /* No wide analog. */
  1073. #ifdef L_memccpy
  1074. void *memccpy(void * __restrict s1, const void * __restrict s2, int c, size_t n)
  1075. {
  1076. register char *r1 = s1;
  1077. register const char *r2 = s2;
  1078. while (n-- && (((unsigned char)(*r1++ = *r2++)) != ((unsigned char) c)));
  1079. return (n == (size_t) -1) ? NULL : r1;
  1080. }
  1081. #endif
  1082. /**********************************************************************/
  1083. #undef Wstrlen
  1084. #undef Wstrcpy
  1085. #ifdef L_wcsdup
  1086. #define L_strdup
  1087. #define Wstrdup wcsdup
  1088. #define Wstrlen wcslen
  1089. #define Wstrcpy wcscpy
  1090. #else
  1091. #define Wstrdup strdup
  1092. #define Wstrlen strlen
  1093. #define Wstrcpy strcpy
  1094. #endif
  1095. #ifdef L_strdup
  1096. Wchar *Wstrdup(register const Wchar *s1)
  1097. {
  1098. register Wchar *s;
  1099. if ((s = malloc((Wstrlen(s1) + 1) * sizeof(Wchar))) != NULL) {
  1100. Wstrcpy(s, s1);
  1101. }
  1102. return s;
  1103. }
  1104. #endif
  1105. /**********************************************************************/
  1106. #ifdef L_strerror
  1107. char *strerror(int errnum)
  1108. {
  1109. static char buf[_STRERROR_BUFSIZE];
  1110. _susv3_strerror_r(errnum, buf, sizeof(buf));
  1111. return buf;
  1112. }
  1113. #endif
  1114. /**********************************************************************/
  1115. /* SUSv3 functions. */
  1116. /**********************************************************************/
  1117. #ifdef L__susv3_strerror_r
  1118. #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
  1119. #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
  1120. static const unsigned char estridx[] = {
  1121. 0, /* success is always 0 */
  1122. EPERM,
  1123. ENOENT,
  1124. ESRCH,
  1125. EINTR,
  1126. EIO,
  1127. ENXIO,
  1128. E2BIG,
  1129. ENOEXEC,
  1130. EBADF,
  1131. ECHILD,
  1132. EAGAIN,
  1133. ENOMEM,
  1134. EACCES,
  1135. EFAULT,
  1136. ENOTBLK,
  1137. EBUSY,
  1138. EEXIST,
  1139. EXDEV,
  1140. ENODEV,
  1141. ENOTDIR,
  1142. EISDIR,
  1143. EINVAL,
  1144. ENFILE,
  1145. EMFILE,
  1146. ENOTTY,
  1147. ETXTBSY,
  1148. EFBIG,
  1149. ENOSPC,
  1150. ESPIPE,
  1151. EROFS,
  1152. EMLINK,
  1153. EPIPE,
  1154. EDOM,
  1155. ERANGE,
  1156. EDEADLK,
  1157. ENAMETOOLONG,
  1158. ENOLCK,
  1159. ENOSYS,
  1160. ENOTEMPTY,
  1161. ELOOP,
  1162. 0,
  1163. ENOMSG,
  1164. EIDRM,
  1165. ECHRNG,
  1166. EL2NSYNC,
  1167. EL3HLT,
  1168. EL3RST,
  1169. ELNRNG,
  1170. EUNATCH,
  1171. ENOCSI,
  1172. EL2HLT,
  1173. EBADE,
  1174. EBADR,
  1175. EXFULL,
  1176. ENOANO,
  1177. EBADRQC,
  1178. EBADSLT,
  1179. 0,
  1180. EBFONT,
  1181. ENOSTR,
  1182. ENODATA,
  1183. ETIME,
  1184. ENOSR,
  1185. ENONET,
  1186. ENOPKG,
  1187. EREMOTE,
  1188. ENOLINK,
  1189. EADV,
  1190. ESRMNT,
  1191. ECOMM,
  1192. EPROTO,
  1193. EMULTIHOP,
  1194. EDOTDOT,
  1195. EBADMSG,
  1196. EOVERFLOW,
  1197. ENOTUNIQ,
  1198. EBADFD,
  1199. EREMCHG,
  1200. ELIBACC,
  1201. ELIBBAD,
  1202. ELIBSCN,
  1203. ELIBMAX,
  1204. ELIBEXEC,
  1205. EILSEQ,
  1206. ERESTART,
  1207. ESTRPIPE,
  1208. EUSERS,
  1209. ENOTSOCK,
  1210. EDESTADDRREQ,
  1211. EMSGSIZE,
  1212. EPROTOTYPE,
  1213. ENOPROTOOPT,
  1214. EPROTONOSUPPORT,
  1215. ESOCKTNOSUPPORT,
  1216. EOPNOTSUPP,
  1217. EPFNOSUPPORT,
  1218. EAFNOSUPPORT,
  1219. EADDRINUSE,
  1220. EADDRNOTAVAIL,
  1221. ENETDOWN,
  1222. ENETUNREACH,
  1223. ENETRESET,
  1224. ECONNABORTED,
  1225. ECONNRESET,
  1226. ENOBUFS,
  1227. EISCONN,
  1228. ENOTCONN,
  1229. ESHUTDOWN,
  1230. ETOOMANYREFS,
  1231. ETIMEDOUT,
  1232. ECONNREFUSED,
  1233. EHOSTDOWN,
  1234. EHOSTUNREACH,
  1235. EALREADY,
  1236. EINPROGRESS,
  1237. ESTALE,
  1238. EUCLEAN,
  1239. ENOTNAM,
  1240. ENAVAIL,
  1241. EISNAM,
  1242. EREMOTEIO,
  1243. #ifdef __mips__
  1244. 0, /* mips has an outrageous value for this... */
  1245. #else
  1246. EDQUOT,
  1247. #endif
  1248. ENOMEDIUM,
  1249. EMEDIUMTYPE,
  1250. #if defined(__mips__) || defined(__sparc__)
  1251. EDEADLOCK,
  1252. #endif
  1253. };
  1254. #endif
  1255. int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
  1256. {
  1257. register char *s;
  1258. int i, retval;
  1259. char buf[_STRERROR_BUFSIZE];
  1260. static const char unknown[] = {
  1261. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
  1262. };
  1263. retval = EINVAL;
  1264. #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
  1265. #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
  1266. /* Need to translate errno to string index. */
  1267. for (i = 0 ; i < sizeof(estridx)/sizeof(estridx[0]) ; i++) {
  1268. if (estridx[i] == errnum) {
  1269. goto GOT_ESTRIDX;
  1270. }
  1271. }
  1272. i = INT_MAX; /* Failed, but may need to check mips special case. */
  1273. #ifdef __mips__
  1274. if (errnum == EDQUOT) { /* Deal with large EDQUOT value on mips */
  1275. i = 122;
  1276. }
  1277. #endif /* __mips__ */
  1278. GOT_ESTRIDX:
  1279. #else
  1280. /* No errno to string index translation needed. */
  1281. i = errnum;
  1282. #endif
  1283. if (((unsigned int) i) < _SYS_NERR) {
  1284. /* Trade time for space. This function should rarely be called
  1285. * so rather than keeping an array of pointers for the different
  1286. * messages, just run through the buffer until we find the
  1287. * correct string. */
  1288. for (s = (char *) _string_syserrmsgs ; i ; ++s) {
  1289. if (!*s) {
  1290. --i;
  1291. }
  1292. }
  1293. if (*s) { /* Make sure we have an actual message. */
  1294. retval = 0;
  1295. goto GOT_MESG;
  1296. }
  1297. }
  1298. #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  1299. s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
  1300. memcpy(s, unknown, sizeof(unknown));
  1301. GOT_MESG:
  1302. if (!strerrbuf) { /* SUSv3 */
  1303. buflen = 0;
  1304. }
  1305. i = strlen(s) + 1;
  1306. if (i > buflen) {
  1307. i = buflen;
  1308. retval = ERANGE;
  1309. }
  1310. if (i) {
  1311. memcpy(strerrbuf, s, i);
  1312. strerrbuf[i-1] = 0; /* In case buf was too small. */
  1313. }
  1314. if (retval) {
  1315. __set_errno(retval);
  1316. }
  1317. return retval;
  1318. }
  1319. #else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  1320. int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
  1321. {
  1322. register char *s;
  1323. int i, retval;
  1324. char buf[_STRERROR_BUFSIZE];
  1325. static const char unknown[] = {
  1326. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
  1327. };
  1328. s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
  1329. memcpy(s, unknown, sizeof(unknown));
  1330. if (!strerrbuf) { /* SUSv3 */
  1331. buflen = 0;
  1332. }
  1333. retval = EINVAL;
  1334. i = buf + sizeof(buf) - s;
  1335. if (i > buflen) {
  1336. i = buflen;
  1337. retval = ERANGE;
  1338. }
  1339. if (i) {
  1340. memcpy(strerrbuf, s, i);
  1341. strerrbuf[i-1] = 0; /* In case buf was too small. */
  1342. }
  1343. __set_errno(retval);
  1344. return retval;
  1345. }
  1346. #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  1347. #endif
  1348. /**********************************************************************/
  1349. /* GNU extension functions. */
  1350. /**********************************************************************/
  1351. #ifdef L__glibc_strerror_r
  1352. weak_alias(_glibc_strerror_r,__strerror_r);
  1353. char *_glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen)
  1354. {
  1355. _susv3_strerror_r(errnum, strerrbuf, buflen);
  1356. return strerrbuf;
  1357. }
  1358. #endif
  1359. /**********************************************************************/
  1360. #ifdef L_memmem
  1361. void *memmem(const void *haystack, size_t haystacklen,
  1362. const void *needle, size_t needlelen)
  1363. {
  1364. register const char *ph;
  1365. register const char *pn;
  1366. const char *plast;
  1367. size_t n;
  1368. if (needlelen == 0) {
  1369. return (void *) haystack;
  1370. }
  1371. if (haystacklen >= needlelen) {
  1372. ph = (const char *) haystack;
  1373. pn = (const char *) needle;
  1374. plast = ph + (haystacklen - needlelen);
  1375. do {
  1376. n = 0;
  1377. while (ph[n] == pn[n]) {
  1378. if (++n == needlelen) {
  1379. return (void *) ph;
  1380. }
  1381. }
  1382. } while (++ph <= plast);
  1383. }
  1384. return NULL;
  1385. }
  1386. #endif
  1387. /**********************************************************************/
  1388. #ifdef L_wmempcpy
  1389. #define L_mempcpy
  1390. #define Wmempcpy wmempcpy
  1391. #else
  1392. #define Wmempcpy mempcpy
  1393. #endif
  1394. #ifdef L_mempcpy
  1395. #ifndef L_wmempcpy
  1396. /* uClibc's old string implementation did this to cater to some app. */
  1397. weak_alias(mempcpy,__mempcpy);
  1398. #endif
  1399. Wvoid *Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
  1400. {
  1401. register Wchar *r1 = s1;
  1402. register const Wchar *r2 = s2;
  1403. #ifdef __BCC__
  1404. while (n--) {
  1405. *r1++ = *r2++;
  1406. }
  1407. #else
  1408. while (n) {
  1409. *r1++ = *r2++;
  1410. --n;
  1411. }
  1412. #endif
  1413. return r1;
  1414. }
  1415. #endif
  1416. /**********************************************************************/
  1417. #ifdef L_memrchr
  1418. void *memrchr(const void *s, int c, size_t n)
  1419. {
  1420. register const unsigned char *r;
  1421. #ifdef __BCC__
  1422. /* bcc can optimize the counter if it thinks it is a pointer... */
  1423. register const char *np = (const char *) n;
  1424. #else
  1425. #define np n
  1426. #endif
  1427. r = ((unsigned char *)s) + ((size_t) np);
  1428. while (np) {
  1429. if (*--r == ((unsigned char)c)) {
  1430. return (void *) r; /* silence the warning */
  1431. }
  1432. --np;
  1433. }
  1434. return NULL;
  1435. }
  1436. #undef np
  1437. #endif
  1438. /**********************************************************************/
  1439. #ifdef L_wcpcpy
  1440. #define L_stpcpy
  1441. #define Wstpcpy wcpcpy
  1442. #else
  1443. #define Wstpcpy stpcpy
  1444. #endif
  1445. #ifdef L_stpcpy
  1446. Wchar *Wstpcpy(register Wchar * __restrict s1, const Wchar * __restrict s2)
  1447. {
  1448. #ifdef __BCC__
  1449. do {
  1450. *s1 = *s2++;
  1451. } while (*s1++ != 0);
  1452. #else
  1453. while ( (*s1++ = *s2++) != 0 );
  1454. #endif
  1455. return s1 - 1;
  1456. }
  1457. #endif
  1458. /**********************************************************************/
  1459. #ifdef L_wcpncpy
  1460. #define L_stpncpy
  1461. #define Wstpncpy wcpncpy
  1462. #else
  1463. #define Wstpncpy stpncpy
  1464. #endif
  1465. #ifdef L_stpncpy
  1466. Wchar *Wstpncpy(register Wchar * __restrict s1,
  1467. register const Wchar * __restrict s2,
  1468. size_t n)
  1469. {
  1470. Wchar *s = s1;
  1471. const Wchar *p = s2;
  1472. #ifdef __BCC__
  1473. while (n--) {
  1474. if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
  1475. ++s;
  1476. }
  1477. return s1 + (s2 - p);
  1478. #else
  1479. while (n) {
  1480. if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
  1481. ++s;
  1482. --n;
  1483. }
  1484. return s1 + (s2 - p);
  1485. #endif
  1486. }
  1487. #endif
  1488. /**********************************************************************/
  1489. #ifdef L_bzero
  1490. void bzero(void *s, size_t n)
  1491. {
  1492. register unsigned char *p = s;
  1493. #ifdef __BCC__
  1494. /* bcc can optimize the counter if it thinks it is a pointer... */
  1495. register const char *np = (const char *) n;
  1496. #else
  1497. #define np n
  1498. #endif
  1499. while (np) {
  1500. *p++ = 0;
  1501. --np;
  1502. }
  1503. }
  1504. #undef np
  1505. #endif
  1506. /**********************************************************************/
  1507. #ifdef L_bcopy
  1508. void bcopy(const void *s2, void *s1, size_t n)
  1509. {
  1510. #if 1
  1511. memmove(s1, s2, n);
  1512. #else
  1513. #ifdef __BCC__
  1514. register char *s;
  1515. register const char *p;
  1516. s = s1;
  1517. p = s2;
  1518. if (p >= s) {
  1519. while (n--) {
  1520. *s++ = *p++;
  1521. }
  1522. } else {
  1523. s += n;
  1524. p += n;
  1525. while (n--) {
  1526. *--s = *--p;
  1527. }
  1528. }
  1529. #else
  1530. register char *s;
  1531. register const char *p;
  1532. s = s1;
  1533. p = s2;
  1534. if (p >= s) {
  1535. while (n) {
  1536. *s++ = *p++;
  1537. --n;
  1538. }
  1539. } else {
  1540. while (n) {
  1541. --n;
  1542. s[n] = p[n];
  1543. }
  1544. }
  1545. #endif
  1546. #endif
  1547. }
  1548. #endif
  1549. /**********************************************************************/
  1550. #ifdef L_strcasestr
  1551. char *strcasestr(const char *s1, const char *s2)
  1552. {
  1553. register const char *s = s1;
  1554. register const char *p = s2;
  1555. #if 1
  1556. do {
  1557. if (!*p) {
  1558. return (char *) s1;;
  1559. }
  1560. if ((*p == *s)
  1561. || (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
  1562. ) {
  1563. ++p;
  1564. ++s;
  1565. } else {
  1566. p = s2;
  1567. if (!*s) {
  1568. return NULL;
  1569. }
  1570. s = ++s1;
  1571. }
  1572. } while (1);
  1573. #else
  1574. while (*p && *s) {
  1575. if ((*p == *s)
  1576. || (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
  1577. ) {
  1578. ++p;
  1579. ++s;
  1580. } else {
  1581. p = s2;
  1582. s = ++s1;
  1583. }
  1584. }
  1585. return (*p) ? NULL : (char *) s1;
  1586. #endif
  1587. }
  1588. #endif
  1589. /**********************************************************************/
  1590. #ifdef L_strndup
  1591. char *strndup(register const char *s1, size_t n)
  1592. {
  1593. register char *s;
  1594. n = strnlen(s1,n); /* Avoid problems if s1 not nul-terminated. */
  1595. if ((s = malloc(n + 1)) != NULL) {
  1596. memcpy(s, s1, n);
  1597. s[n] = 0;
  1598. }
  1599. return s;
  1600. }
  1601. #endif
  1602. /**********************************************************************/
  1603. #ifdef L_strsep
  1604. char *strsep(char ** __restrict s1, const char * __restrict s2)
  1605. {
  1606. register char *s = *s1;
  1607. register char *p;
  1608. #if 1
  1609. p = NULL;
  1610. if (s && *s && (p = strpbrk(s, s2))) {
  1611. *p++ = 0;
  1612. }
  1613. #else
  1614. if (s && *s && *(p = s + strcspn(s, s2))) {
  1615. *p++ = 0;
  1616. } else {
  1617. p = NULL;
  1618. }
  1619. #endif
  1620. *s1 = p;
  1621. return s;
  1622. }
  1623. #endif
  1624. /**********************************************************************/
  1625. #ifdef L_wcschrnul
  1626. #define L_strchrnul
  1627. #define __Wstrchrnul __wcschrnul
  1628. #define Wstrchrnul wcschrnul
  1629. #else
  1630. #define __Wstrchrnul __strchrnul
  1631. #define Wstrchrnul strchrnul
  1632. #endif
  1633. #ifdef L_strchrnul
  1634. extern Wchar *__Wstrchrnul(register const Wchar *s, Wint c);
  1635. weak_alias(__Wstrchrnul, Wstrchrnul);
  1636. Wchar *__Wstrchrnul(register const Wchar *s, Wint c)
  1637. {
  1638. --s;
  1639. while (*++s && (*s != ((Wchar)c)));
  1640. return (Wchar *) s;
  1641. }
  1642. #endif
  1643. /**********************************************************************/
  1644. #ifdef L_rawmemchr
  1645. void *rawmemchr(const void *s, int c)
  1646. {
  1647. register const unsigned char *r = s;
  1648. while (*r != ((unsigned char)c)) ++r;
  1649. return (void *) r; /* silence the warning */
  1650. }
  1651. #endif
  1652. /**********************************************************************/
  1653. #ifdef L_basename
  1654. char *basename(const char *path)
  1655. {
  1656. register const char *s;
  1657. register const char *p;
  1658. p = s = path;
  1659. while (*s) {
  1660. if (*s++ == '/') {
  1661. p = s;
  1662. }
  1663. }
  1664. return (char *) p;
  1665. }
  1666. #endif
  1667. /**********************************************************************/
  1668. #ifdef L___xpg_basename
  1669. char *__xpg_basename(register char *path)
  1670. {
  1671. static const char null_or_empty[] = ".";
  1672. char *first;
  1673. register char *last;
  1674. first = (char *) null_or_empty;
  1675. if (path && *path) {
  1676. first = path;
  1677. last = path - 1;
  1678. do {
  1679. if ((*path != '/') && (path > ++last)) {
  1680. last = first = path;
  1681. }
  1682. } while (*++path);
  1683. if (*first == '/') {
  1684. last = first;
  1685. }
  1686. last[1] = 0;
  1687. }
  1688. return first;
  1689. }
  1690. #endif
  1691. /**********************************************************************/
  1692. #ifdef L_dirname
  1693. char *dirname(char *path)
  1694. {
  1695. static const char null_or_empty_or_noslash[] = ".";
  1696. register char *s;
  1697. register char *last;
  1698. char *first;
  1699. last = s = path;
  1700. if (s != NULL) {
  1701. LOOP:
  1702. while (*s && (*s != '/')) ++s;
  1703. first = s;
  1704. while (*s == '/') ++s;
  1705. if (*s) {
  1706. last = first;
  1707. goto LOOP;
  1708. }
  1709. if (last == path) {
  1710. if (*last != '/') {
  1711. goto DOT;
  1712. }
  1713. if ((*++last == '/') && (last[1] == 0)) {
  1714. ++last;
  1715. }
  1716. }
  1717. *last = 0;
  1718. return path;
  1719. }
  1720. DOT:
  1721. return (char *) null_or_empty_or_noslash;
  1722. }
  1723. #endif
  1724. /**********************************************************************/
  1725. #ifdef L_strlcat
  1726. /* OpenBSD function:
  1727. * Append at most n-1-strlen(dst) chars from src to dst and nul-terminate dst.
  1728. * Returns strlen(src) + strlen({original} dst), so truncation occurred if the
  1729. * return val is >= n.
  1730. * Note: If dst doesn't contain a nul in the first n chars, strlen(dst) is
  1731. * taken as n. */
  1732. size_t strlcat(register char *__restrict dst,
  1733. register const char *__restrict src,
  1734. size_t n)
  1735. {
  1736. size_t len;
  1737. char dummy[1];
  1738. len = 0;
  1739. while (1) {
  1740. if (len >= n) {
  1741. dst = dummy;
  1742. break;
  1743. }
  1744. if (!*dst) {
  1745. break;
  1746. }
  1747. ++dst;
  1748. ++len;
  1749. }
  1750. while ((*dst = *src) != 0) {
  1751. if (++len < n) {
  1752. ++dst;
  1753. }
  1754. ++src;
  1755. }
  1756. return len;
  1757. }
  1758. #endif
  1759. /**********************************************************************/
  1760. #ifdef WANT_WIDE
  1761. extern size_t __wcslcpy(wchar_t *__restrict dst,
  1762. const wchar_t *__restrict src,
  1763. size_t n);
  1764. #endif
  1765. #ifdef L___wcslcpy
  1766. #define L_strlcpy
  1767. #define Wstrlcpy __wcslcpy
  1768. #ifdef __LOCALE_C_ONLY
  1769. weak_alias(__wcslcpy,wcsxfrm);
  1770. #endif
  1771. #endif
  1772. #ifdef L_strlcpy
  1773. #ifndef L___wcslcpy
  1774. #define Wstrlcpy strlcpy
  1775. #ifdef __LOCALE_C_ONLY
  1776. weak_alias(strlcpy,strxfrm);
  1777. #endif
  1778. #endif
  1779. /* OpenBSD function:
  1780. * Copy at most n-1 chars from src to dst and nul-terminate dst.
  1781. * Returns strlen(src), so truncation occurred if the return value is >= n. */
  1782. size_t Wstrlcpy(register Wchar *__restrict dst,
  1783. register const Wchar *__restrict src,
  1784. size_t n)
  1785. {
  1786. const Wchar *src0 = src;
  1787. Wchar dummy[1];
  1788. if (!n) {
  1789. dst = dummy;
  1790. } else {
  1791. --n;
  1792. }
  1793. while ((*dst = *src) != 0) {
  1794. if (n) {
  1795. --n;
  1796. ++dst;
  1797. }
  1798. ++src;
  1799. }
  1800. return src - src0;
  1801. }
  1802. #endif
  1803. /**********************************************************************/
  1804. #if defined(L__string_syssigmsgs) && defined(__UCLIBC_HAS_SIGNUM_MESSAGES__)
  1805. const char _string_syssigmsgs[] = {
  1806. /* 0: 0, 1 */ "\0"
  1807. /* 1: 1, 7 */ "Hangup\0"
  1808. /* 2: 8, 10 */ "Interrupt\0"
  1809. /* 3: 18, 5 */ "Quit\0"
  1810. /* 4: 23, 20 */ "Illegal instruction\0"
  1811. /* 5: 43, 22 */ "Trace/breakpoint trap\0"
  1812. /* 6: 65, 8 */ "Aborted\0"
  1813. /* 7: 73, 10 */ "Bus error\0"
  1814. /* 8: 83, 25 */ "Floating point exception\0"
  1815. /* 9: 108, 7 */ "Killed\0"
  1816. /* 10: 115, 22 */ "User defined signal 1\0"
  1817. /* 11: 137, 19 */ "Segmentation fault\0"
  1818. /* 12: 156, 22 */ "User defined signal 2\0"
  1819. /* 13: 178, 12 */ "Broken pipe\0"
  1820. /* 14: 190, 12 */ "Alarm clock\0"
  1821. /* 15: 202, 11 */ "Terminated\0"
  1822. /* 16: 213, 12 */ "Stack fault\0"
  1823. /* 17: 225, 13 */ "Child exited\0"
  1824. /* 18: 238, 10 */ "Continued\0"
  1825. /* 19: 248, 17 */ "Stopped (signal)\0"
  1826. /* 20: 265, 8 */ "Stopped\0"
  1827. /* 21: 273, 20 */ "Stopped (tty input)\0"
  1828. /* 22: 293, 21 */ "Stopped (tty output)\0"
  1829. /* 23: 314, 21 */ "Urgent I/O condition\0"
  1830. /* 24: 335, 24 */ "CPU time limit exceeded\0"
  1831. /* 25: 359, 25 */ "File size limit exceeded\0"
  1832. /* 26: 384, 22 */ "Virtual timer expired\0"
  1833. /* 27: 406, 24 */ "Profiling timer expired\0"
  1834. /* 28: 430, 15 */ "Window changed\0"
  1835. /* 29: 445, 13 */ "I/O possible\0"
  1836. /* 30: 458, 14 */ "Power failure\0"
  1837. /* 31: 472, 16 */ "Bad system call"
  1838. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1839. /* 32: 488, 9 */ "\0EMT trap"
  1840. #endif
  1841. };
  1842. #endif
  1843. /**********************************************************************/
  1844. #if defined(L_sys_siglist) && defined(__UCLIBC_HAS_SYS_SIGLIST__)
  1845. const char *const sys_siglist[_NSIG] = {
  1846. [0] = NULL,
  1847. [SIGHUP] = _string_syssigmsgs + 1,
  1848. [SIGINT] = _string_syssigmsgs + 8,
  1849. [SIGQUIT] = _string_syssigmsgs + 18,
  1850. [SIGILL] = _string_syssigmsgs + 23,
  1851. [SIGTRAP] = _string_syssigmsgs + 43,
  1852. [SIGABRT] = _string_syssigmsgs + 65,
  1853. [SIGBUS] = _string_syssigmsgs + 73,
  1854. [SIGFPE] = _string_syssigmsgs + 83,
  1855. [SIGKILL] = _string_syssigmsgs + 108,
  1856. [SIGUSR1] = _string_syssigmsgs + 115,
  1857. [SIGSEGV] = _string_syssigmsgs + 137,
  1858. [SIGUSR2] = _string_syssigmsgs + 156,
  1859. [SIGPIPE] = _string_syssigmsgs + 178,
  1860. [SIGALRM] = _string_syssigmsgs + 190,
  1861. [SIGTERM] = _string_syssigmsgs + 202,
  1862. #if !(defined(__alpha__) || defined(__mips__) || defined(__sparc__))
  1863. [SIGSTKFLT] = _string_syssigmsgs + 213,
  1864. #endif
  1865. [SIGCHLD] = _string_syssigmsgs + 225,
  1866. [SIGCONT] = _string_syssigmsgs + 238,
  1867. [SIGSTOP] = _string_syssigmsgs + 248,
  1868. [SIGTSTP] = _string_syssigmsgs + 265,
  1869. [SIGTTIN] = _string_syssigmsgs + 273,
  1870. [SIGTTOU] = _string_syssigmsgs + 293,
  1871. [SIGURG] = _string_syssigmsgs + 314,
  1872. [SIGXCPU] = _string_syssigmsgs + 335,
  1873. [SIGXFSZ] = _string_syssigmsgs + 359,
  1874. [SIGVTALRM] = _string_syssigmsgs + 384,
  1875. [SIGPROF] = _string_syssigmsgs + 406,
  1876. [SIGWINCH] = _string_syssigmsgs + 430,
  1877. [SIGIO] = _string_syssigmsgs + 445,
  1878. [SIGPWR] = _string_syssigmsgs + 458,
  1879. [SIGSYS] = _string_syssigmsgs + 472,
  1880. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1881. [SIGEMT] = _string_syssigmsgs + 488,
  1882. #endif
  1883. };
  1884. #endif
  1885. /**********************************************************************/
  1886. #ifdef L_strsignal
  1887. /* TODO: make a threadsafe version? */
  1888. #ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__
  1889. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1890. static const unsigned char sstridx[] = {
  1891. 0,
  1892. SIGHUP,
  1893. SIGINT,
  1894. SIGQUIT,
  1895. SIGILL,
  1896. SIGTRAP,
  1897. SIGIOT,
  1898. SIGBUS,
  1899. SIGFPE,
  1900. SIGKILL,
  1901. SIGUSR1,
  1902. SIGSEGV,
  1903. SIGUSR2,
  1904. SIGPIPE,
  1905. SIGALRM,
  1906. SIGTERM,
  1907. #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
  1908. 0,
  1909. #else
  1910. SIGSTKFLT,
  1911. #endif
  1912. SIGCHLD,
  1913. SIGCONT,
  1914. SIGSTOP,
  1915. SIGTSTP,
  1916. SIGTTIN,
  1917. SIGTTOU,
  1918. SIGURG,
  1919. SIGXCPU,
  1920. SIGXFSZ,
  1921. SIGVTALRM,
  1922. SIGPROF,
  1923. SIGWINCH,
  1924. SIGIO,
  1925. SIGPWR,
  1926. SIGSYS,
  1927. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1928. SIGEMT,
  1929. #endif
  1930. };
  1931. #endif
  1932. char *strsignal(int signum)
  1933. {
  1934. register char *s;
  1935. int i;
  1936. static char buf[_STRSIGNAL_BUFSIZE];
  1937. static const char unknown[] = {
  1938. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' '
  1939. };
  1940. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1941. /* Need to translate signum to string index. */
  1942. for (i = 0 ; i < sizeof(sstridx)/sizeof(sstridx[0]) ; i++) {
  1943. if (sstridx[i] == signum) {
  1944. goto GOT_SSTRIDX;
  1945. }
  1946. }
  1947. i = INT_MAX; /* Failed. */
  1948. GOT_SSTRIDX:
  1949. #else
  1950. /* No signum to string index translation needed. */
  1951. i = signum;
  1952. #endif
  1953. if (((unsigned int) signum) < _SYS_NSIG) {
  1954. /* Trade time for space. This function should rarely be called
  1955. * so rather than keeping an array of pointers for the different
  1956. * messages, just run through the buffer until we find the
  1957. * correct string. */
  1958. for (s = (char *) _string_syssigmsgs ; i ; ++s) {
  1959. if (!*s) {
  1960. --i;
  1961. }
  1962. }
  1963. if (*s) { /* Make sure we have an actual message. */
  1964. goto DONE;
  1965. }
  1966. }
  1967. s = _int10tostr(buf+sizeof(buf)-1, signum) - sizeof(unknown);
  1968. memcpy(s, unknown, sizeof(unknown));
  1969. DONE:
  1970. return s;
  1971. }
  1972. #else /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
  1973. char *strsignal(int signum)
  1974. {
  1975. static char buf[_STRSIGNAL_BUFSIZE];
  1976. static const char unknown[] = {
  1977. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' '
  1978. };
  1979. return (char *) memcpy(_int10tostr(buf+sizeof(buf)-1, signum)
  1980. - sizeof(unknown),
  1981. unknown, sizeof(unknown));
  1982. }
  1983. #endif /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
  1984. #endif
  1985. /**********************************************************************/
  1986. #ifdef L_psignal
  1987. /* TODO: make this threadsafe with a reentrant version of strsignal? */
  1988. void psignal(int signum, register const char *message)
  1989. {
  1990. /* If the program is calling psignal, it's a safe bet that printf and
  1991. * friends are used as well. It is also possible that the calling
  1992. * program could buffer stderr, or reassign it. */
  1993. register const char *sep;
  1994. sep = ": ";
  1995. if (!(message && *message)) { /* Caller did not supply a prefix message */
  1996. message = (sep += 2); /* or passed an empty string. */
  1997. }
  1998. #if 1
  1999. fprintf(stderr, "%s%s%s\n", message, sep, strsignal(signum));
  2000. #else
  2001. /* Note: Assumes stderr not closed or buffered. */
  2002. __STDIO_THREADLOCK(stderr);
  2003. _stdio_fdout(STDERR_FILENO, message, sep, strsignal(signum));
  2004. __STDIO_THREADUNLOCK(stderr);
  2005. #endif
  2006. }
  2007. #endif
  2008. /**********************************************************************/
  2009. #ifndef __LOCALE_C_ONLY
  2010. #if defined(L_strxfrm) || defined(L_strxfrm_l) || defined(L_wcsxfrm) || defined(L_wcsxfrm_l)
  2011. #ifdef L_strxfrm
  2012. #ifndef WANT_WIDE
  2013. #error WANT_WIDE should be defined for L_strxfrm
  2014. #endif
  2015. #ifdef L_wcsxfrm
  2016. #error L_wcsxfrm already defined for L_strxfrm
  2017. #endif
  2018. #endif /* L_strxfrm */
  2019. #if defined(L_strxfrm) || defined(L_strxfrm_l)
  2020. #define wcscoll strcoll
  2021. #define wcscoll_l strcoll_l
  2022. #define __wcscoll_l __strcoll_l
  2023. #define wcsxfrm strxfrm
  2024. #define wcsxfrm_l strxfrm_l
  2025. #define __wcsxfrm_l __strxfrm_l
  2026. #undef WANT_WIDE
  2027. #undef Wvoid
  2028. #undef Wchar
  2029. #undef Wuchar
  2030. #undef Wint
  2031. #define Wchar char
  2032. #endif /* defined(L_strxfrm) || defined(L_strxfrm_l) */
  2033. #if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
  2034. int wcscoll (const Wchar *s0, const Wchar *s1)
  2035. {
  2036. return __wcscoll_l(s0, s1, __UCLIBC_CURLOCALE );
  2037. }
  2038. size_t wcsxfrm(Wchar *__restrict ws1, const Wchar *__restrict ws2, size_t n)
  2039. {
  2040. return __wcsxfrm_l(ws1, ws2, n, __UCLIBC_CURLOCALE );
  2041. }
  2042. #else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  2043. #if 0
  2044. #define CUR_COLLATE (&__UCLIBC_CURLOCALE_DATA.collate)
  2045. #else
  2046. #define CUR_COLLATE (& __LOCALE_PTR->collate)
  2047. #endif
  2048. #define MAX_PENDING 8
  2049. typedef struct {
  2050. const Wchar *s;
  2051. const Wchar *eob; /* end of backward */
  2052. __uwchar_t weight;
  2053. __uwchar_t ui_weight; /* undefined or invalid */
  2054. int colitem;
  2055. int weightidx;
  2056. int rule;
  2057. size_t position;
  2058. /* should be wchar_t. if wchar < 0 do EILSEQ? */
  2059. __uwchar_t *cip;
  2060. __uwchar_t ci_pending[MAX_PENDING]; /* nul-terminated */
  2061. char *back_buf;
  2062. char *bbe; /* end of back_buf (actual last... not 1 past end) */
  2063. char *bp; /* ptr into backbuf, NULL if not in backward mode */
  2064. char ibb[128];
  2065. size_t bb_size;
  2066. int ru_pushed;
  2067. } col_state_t;
  2068. #define WEIGHT_MASK 0x3fffU
  2069. #define RULE_MASK 0xc000U
  2070. #define RULE_FORWARD (1 << 14)
  2071. #define RULE_POSITION (1 << 15)
  2072. #define UI_IDX (WEIGHT_MASK-6)
  2073. #define POSIT_IDX (WEIGHT_MASK-5)
  2074. #define RANGE_IDX (WEIGHT_MASK-4)
  2075. #define UNDEF_IDX (WEIGHT_MASK-3)
  2076. #define INVAL_IDX (WEIGHT_MASK-2)
  2077. #define DITTO_IDX (WEIGHT_MASK-1)
  2078. #undef TRACE
  2079. #if 0
  2080. #define TRACE(X) printf X
  2081. #else
  2082. #define TRACE(X) ((void)0)
  2083. #endif
  2084. static int lookup(wchar_t wc __LOCALE_PARAM )
  2085. {
  2086. unsigned int sc, n, i0, i1;
  2087. if (((__uwchar_t) wc) > 0xffffU) {
  2088. return 0;
  2089. }
  2090. sc = wc & CUR_COLLATE->ti_mask;
  2091. wc >>= CUR_COLLATE->ti_shift;
  2092. n = wc & CUR_COLLATE->ii_mask;
  2093. wc >>= CUR_COLLATE->ii_shift;
  2094. i0 = CUR_COLLATE->wcs2colidt_tbl[wc];
  2095. i0 <<= CUR_COLLATE->ii_shift;
  2096. i1 = CUR_COLLATE->wcs2colidt_tbl[CUR_COLLATE->ii_len + i0 + n];
  2097. i1 <<= CUR_COLLATE->ti_shift;
  2098. return CUR_COLLATE->wcs2colidt_tbl[CUR_COLLATE->ii_len + CUR_COLLATE->ti_len + i1 + sc];
  2099. }
  2100. static void init_col_state(col_state_t *cs, const Wchar *wcs)
  2101. {
  2102. memset(cs, 0, sizeof(col_state_t));
  2103. cs->s = wcs;
  2104. cs->bp = cs->back_buf = cs->ibb;
  2105. cs->bb_size = 128;
  2106. cs->bbe = cs->back_buf + (cs->bb_size -1);
  2107. }
  2108. static void next_weight(col_state_t *cs, int pass __LOCALE_PARAM )
  2109. {
  2110. int r, w, ru, ri, popping_backup_stack;
  2111. ssize_t n;
  2112. const uint16_t *p;
  2113. #ifdef WANT_WIDE
  2114. #define WC (*cs->s)
  2115. #define N (1)
  2116. #else /* WANT_WIDE */
  2117. wchar_t WC;
  2118. size_t n0, nx;
  2119. #define N n0
  2120. #endif /* WANT_WIDE */
  2121. do {
  2122. if (cs->ru_pushed) {
  2123. ru = cs->ru_pushed;
  2124. TRACE(("ru_pushed = %d\n", ru));
  2125. cs->ru_pushed = 0;
  2126. goto POSITION_SKIP;
  2127. }
  2128. #ifdef __UCLIBC_MJN3_ONLY__
  2129. #warning should we walk pendings backwards?
  2130. #endif
  2131. if (cs->cip) { /* possible pending weight */
  2132. if ((r = *(cs->cip++)) == 0) {
  2133. cs->cip = NULL;
  2134. continue;
  2135. }
  2136. cs->weightidx = r & WEIGHT_MASK;
  2137. assert(cs->weightidx);
  2138. /* assert(cs->weightidx != WEIGHT_MASK); */
  2139. } else { /* get the next collation item from the string */
  2140. TRACE(("clearing popping flag\n"));
  2141. popping_backup_stack = 0;
  2142. IGNORE_LOOP:
  2143. /* keep first pos as 0 for a sentinal */
  2144. if (*cs->bp) { /* pending backward chars */
  2145. POP_BACKUP:
  2146. popping_backup_stack = 1;
  2147. TRACE(("setting popping flag\n"));
  2148. n = 0;
  2149. if (*cs->bp > 0) { /* singles pending */
  2150. cs->s -= 1;
  2151. if ((*cs->bp -= 1) == 0) {
  2152. cs->bp -= 1;
  2153. }
  2154. } else { /* last was a multi */
  2155. cs->s += *cs->bp;
  2156. cs->bp -= 1;
  2157. }
  2158. } else if (!*cs->s) { /* not in backward mode and end of string */
  2159. cs->weight = 0;
  2160. return;
  2161. } else {
  2162. cs->position += 1;
  2163. }
  2164. BACK_LOOP:
  2165. #ifdef WANT_WIDE
  2166. n = 1;
  2167. cs->colitem = r = lookup(*cs->s __LOCALE_ARG );
  2168. #else /* WANT_WIDE */
  2169. n = n0 = __locale_mbrtowc_l(&WC, cs->s, __LOCALE_PTR);
  2170. if (n < 0) {
  2171. __set_errno(EILSEQ);
  2172. cs->weight = 0;
  2173. return;
  2174. }
  2175. cs->colitem = r = lookup(WC __LOCALE_ARG );
  2176. #endif /* WANT_WIDE */
  2177. TRACE((" r=%d WC=%#lx\n", r, (unsigned long)(WC)));
  2178. if (r > CUR_COLLATE->max_col_index) { /* starting char for one or more sequences */
  2179. p = CUR_COLLATE->multistart_tbl;
  2180. p += p[r-CUR_COLLATE->max_col_index -1];
  2181. do {
  2182. n = N;
  2183. r = *p++;
  2184. do {
  2185. if (!*p) { /* found it */
  2186. cs->colitem = r;
  2187. TRACE((" found multi %d\n", n));
  2188. goto FOUND;
  2189. }
  2190. #ifdef WANT_WIDE
  2191. /* the lookup check here is safe since we're assured that *p is a valid colidx */
  2192. if (!cs->s[n] || (lookup(cs->s[n] __LOCALE_ARG ) != *p)) {
  2193. do {} while (*p++);
  2194. break;
  2195. }
  2196. ++p;
  2197. ++n;
  2198. #else /* WANT_WIDE */
  2199. if (cs->s[n]) {
  2200. nx = __locale_mbrtowc_l(&WC, cs->s + n, __LOCALE_PTR);
  2201. if (nx < 0) {
  2202. __set_errno(EILSEQ);
  2203. cs->weight = 0;
  2204. return;
  2205. }
  2206. }
  2207. if (!cs->s[n] || (lookup(WC __LOCALE_ARG ) != *p)) {
  2208. do {} while (*p++);
  2209. break;
  2210. }
  2211. ++p;
  2212. n += nx; /* Only gets here if cs->s[n] != 0, so nx is set. */
  2213. #endif /* WANT_WIDE */
  2214. } while (1);
  2215. } while (1);
  2216. } else if (r == 0) { /* illegal, undefined, or part of a range */
  2217. if ((CUR_COLLATE->range_count)
  2218. #ifdef __UCLIBC_MJN3_ONLY__
  2219. #warning .. need to introduce range as a collating item?
  2220. #endif
  2221. && (((__uwchar_t)(WC - CUR_COLLATE->range_low)) <= CUR_COLLATE->range_count)
  2222. ) { /* part of a range */
  2223. /* Note: cs->colitem = 0 already. */
  2224. TRACE((" found range\n"));
  2225. ru = CUR_COLLATE->ruletable[CUR_COLLATE->range_rule_offset*CUR_COLLATE->MAX_WEIGHTS + pass];
  2226. assert((ru & WEIGHT_MASK) != DITTO_IDX);
  2227. if ((ru & WEIGHT_MASK) == WEIGHT_MASK) {
  2228. ru = (ru & RULE_MASK) | RANGE_IDX;
  2229. cs->weight = CUR_COLLATE->range_base_weight + (WC - CUR_COLLATE->range_low);
  2230. }
  2231. goto RANGE_SKIP_TO;
  2232. } else if (((__uwchar_t)(WC)) <= 0x7fffffffUL) { /* legal but undefined */
  2233. UNDEFINED:
  2234. /* Note: cs->colitem = 0 already. */
  2235. ri = CUR_COLLATE->undefined_idx;
  2236. assert(ri != 0); /* implicit undefined isn't supported */
  2237. TRACE((" found explicit UNDEFINED\n"));
  2238. #ifdef __UCLIBC_MJN3_ONLY__
  2239. #warning right now single weight locales do not support ..
  2240. #endif
  2241. if (CUR_COLLATE->num_weights == 1) {
  2242. TRACE((" single weight UNDEFINED\n"));
  2243. cs->weightidx = RANGE_IDX;
  2244. cs->weight = ri;
  2245. cs->s += n;
  2246. goto PROCESS_WEIGHT;
  2247. }
  2248. ri = CUR_COLLATE->index2ruleidx[ri - 1];
  2249. ru = CUR_COLLATE->ruletable[ri * CUR_COLLATE->MAX_WEIGHTS + pass];
  2250. assert((ru & WEIGHT_MASK) != WEIGHT_MASK); /* TODO: handle ".." */
  2251. if ((ru & WEIGHT_MASK) == DITTO_IDX) {
  2252. cs->colitem = CUR_COLLATE->undefined_idx;
  2253. }
  2254. goto RANGE_SKIP_TO;
  2255. } else { /* illegal */
  2256. TRACE((" found illegal\n"));
  2257. __set_errno(EINVAL);
  2258. /* We put all illegals in the same equiv class with maximal weight,
  2259. * and ignore them after the first pass. */
  2260. if (pass > 0) {
  2261. cs->s += n;
  2262. goto IGNORE_LOOP;
  2263. }
  2264. ru = (RULE_FORWARD | RANGE_IDX);
  2265. cs->weight = 0xffffU;
  2266. goto RANGE_SKIP_TO;
  2267. }
  2268. } else if (CUR_COLLATE->num_weights == 1) {
  2269. TRACE((" single weight\n"));
  2270. cs->weightidx = RANGE_IDX;
  2271. cs->weight = cs->colitem;
  2272. cs->s += n;
  2273. goto PROCESS_WEIGHT;
  2274. } else {
  2275. TRACE((" normal\n"));
  2276. }
  2277. /* if we get here, it is a normal char either singlely weighted, undefined, or in a range */
  2278. FOUND:
  2279. ri = CUR_COLLATE->index2ruleidx[cs->colitem - 1];
  2280. TRACE((" ri=%d ", ri));
  2281. #ifdef __UCLIBC_MJN3_ONLY__
  2282. #warning make sure this is correct
  2283. #endif
  2284. if (!ri) {
  2285. TRACE(("NOT IN THIS LOCALE\n"));
  2286. goto UNDEFINED;
  2287. }
  2288. ru = CUR_COLLATE->ruletable[ri * CUR_COLLATE->MAX_WEIGHTS + pass];
  2289. RANGE_SKIP_TO:
  2290. #ifdef __UCLIBC_MJN3_ONLY__
  2291. #warning ignoreables probably should not interrupt backwards processing, but this is wrong
  2292. #endif
  2293. /* if (!(ru & WEIGHT_MASK)) { */
  2294. /* TRACE(("IGNORE\n")); */
  2295. /* cs->s += n; */
  2296. /* continue; */
  2297. /* } */
  2298. TRACE((" rule = %#x weight = %#x popping = %d s = %p eob = %p\n",
  2299. ru & RULE_MASK, ru & WEIGHT_MASK, popping_backup_stack,
  2300. cs->s, cs->eob));
  2301. /* now we need to check if we're going backwards... */
  2302. if (!popping_backup_stack) {
  2303. if (!(ru & RULE_MASK)) { /* backward */
  2304. TRACE(("backwards\n"));
  2305. assert(cs->bp <= cs->bbe);
  2306. if (cs->bp == cs->bbe) {
  2307. if (cs->back_buf == cs->ibb) { /* was using internal buffer */
  2308. cs->bp = malloc(cs->bb_size + 128);
  2309. if (!cs->bp) {
  2310. __set_errno(ENOMEM);
  2311. #ifdef __UCLIBC_MJN3_ONLY__
  2312. #warning what to do here?
  2313. #endif
  2314. cs->weight = 0;
  2315. return;
  2316. }
  2317. memcpy(cs->bp, cs->back_buf, cs->bb_size);
  2318. } else {
  2319. cs->bp = realloc(cs->back_buf, cs->bb_size + 128);
  2320. if (!cs->bp) {
  2321. __set_errno(ENOMEM);
  2322. #ifdef __UCLIBC_MJN3_ONLY__
  2323. #warning what to do here?
  2324. #endif
  2325. cs->weight = 0;
  2326. return;
  2327. }
  2328. }
  2329. cs->bb_size += 128;
  2330. cs->bbe = cs->bp + (cs->bbe - cs->back_buf);
  2331. cs->back_buf = cs->bp;
  2332. cs->bp = cs->bbe;
  2333. }
  2334. if (n==1) { /* single char */
  2335. if (*cs->bp && (((unsigned char)(*cs->bp)) < CHAR_MAX)) {
  2336. *cs->bp += 1; /* increment last single's count */
  2337. } else { /* last was a multi, or just starting */
  2338. if (!cs->bp) {
  2339. cs->bp = cs->back_buf;
  2340. } else {
  2341. assert(cs->bp < cs->bbe);
  2342. ++cs->bp;
  2343. }
  2344. *cs->bp = 1;
  2345. }
  2346. } else { /* multichar */
  2347. assert(n>1);
  2348. assert(cs->bp < cs->bbe);
  2349. *++cs->bp = -n;
  2350. }
  2351. cs->s += n;
  2352. if (*cs->s) {
  2353. goto BACK_LOOP;
  2354. }
  2355. /* end-of-string so start popping */
  2356. cs->eob = cs->s;
  2357. TRACE(("popping\n"));
  2358. goto POP_BACKUP;
  2359. } else if (*cs->bp) { /* was going backward but this element isn't */
  2360. /* discard current and use previous backward element */
  2361. assert(!cs->cip);
  2362. cs->eob = cs->s;
  2363. TRACE(("popping\n"));
  2364. goto POP_BACKUP;
  2365. } else { /* was and still going forward */
  2366. TRACE(("forwards\n"));
  2367. if ((ru & (RULE_POSITION|WEIGHT_MASK)) > RULE_POSITION) {
  2368. assert(ru & WEIGHT_MASK);
  2369. cs->ru_pushed = ru;
  2370. cs->weight = cs->position;
  2371. #ifdef __UCLIBC_MJN3_ONLY__
  2372. #warning devel code
  2373. #endif
  2374. cs->position = 0; /* reset to reduce size for strcoll? */
  2375. cs->s += n;
  2376. cs->weightidx = RANGE_IDX;
  2377. goto PROCESS_WEIGHT;
  2378. }
  2379. }
  2380. } else { /* popping backwards stack */
  2381. TRACE(("popping (continued)\n"));
  2382. if (!*cs->bp) {
  2383. cs->s = cs->eob;
  2384. }
  2385. cs->s -= n;
  2386. }
  2387. cs->s += n;
  2388. POSITION_SKIP:
  2389. cs->weightidx = ru & WEIGHT_MASK;
  2390. cs->rule = ru & RULE_MASK;
  2391. }
  2392. #ifdef __UCLIBC_MJN3_ONLY__
  2393. #warning for pending we only want the weight... _not_ the rule
  2394. #endif
  2395. if (!cs->weightidx) { /* ignore */
  2396. continue;
  2397. }
  2398. PROCESS_WEIGHT:
  2399. assert(cs->weightidx);
  2400. if (((unsigned int)(cs->weightidx - UI_IDX)) <= (INVAL_IDX-UI_IDX)) {
  2401. if (cs->weightidx == UI_IDX) {
  2402. cs->weight = cs->ui_weight;
  2403. }
  2404. return;
  2405. }
  2406. assert(cs->weightidx != WEIGHT_MASK);
  2407. if (cs->weightidx == DITTO_IDX) { /* want the weight of the current collating item */
  2408. TRACE(("doing ditto\n"));
  2409. w = CUR_COLLATE->index2weight[cs->colitem -1];
  2410. } else if (cs->weightidx <= CUR_COLLATE->max_col_index) { /* normal */
  2411. TRACE(("doing normal\n"));
  2412. w = CUR_COLLATE->index2weight[cs->weightidx -1];
  2413. } else { /* a string */
  2414. TRACE(("doing string\n"));
  2415. assert(!(cs->weightidx & RULE_MASK));
  2416. /* note: iso14561 allows null string here */
  2417. p = CUR_COLLATE->weightstr + (cs->weightidx - (CUR_COLLATE->max_col_index + 2));
  2418. if (*p & WEIGHT_MASK) {
  2419. r = 0;
  2420. do {
  2421. assert(r < MAX_PENDING);
  2422. cs->ci_pending[r++] = *p++;
  2423. } while (*p & WEIGHT_MASK);
  2424. cs->cip = cs->ci_pending;
  2425. }
  2426. continue;
  2427. }
  2428. cs->weight = w;
  2429. return;
  2430. } while (1);
  2431. }
  2432. int __XL(wcscoll) (const Wchar *s0, const Wchar *s1 __LOCALE_PARAM )
  2433. {
  2434. col_state_t ws[2];
  2435. int pass;
  2436. if (!CUR_COLLATE->num_weights) { /* C locale */
  2437. #ifdef WANT_WIDE
  2438. return wcscmp(s0, s1);
  2439. #else /* WANT_WIDE */
  2440. return strcmp(s0, s1);
  2441. #endif /* WANT_WIDE */
  2442. }
  2443. pass = 0;
  2444. do { /* loop through the weights levels */
  2445. init_col_state(ws, s0);
  2446. init_col_state(ws+1, s1);
  2447. do { /* loop through the strings */
  2448. /* for each string, get the next weight */
  2449. next_weight(ws, pass __LOCALE_ARG );
  2450. next_weight(ws+1, pass __LOCALE_ARG );
  2451. TRACE(("w0=%lu w1=%lu\n",
  2452. (unsigned long) ws[0].weight,
  2453. (unsigned long) ws[1].weight));
  2454. if (ws[0].weight != ws[1].weight) {
  2455. return ws[0].weight - ws[1].weight;
  2456. }
  2457. } while (ws[0].weight);
  2458. } while (++pass < CUR_COLLATE->num_weights);
  2459. return 0;
  2460. }
  2461. __XL_ALIAS(wcscoll)
  2462. #ifdef WANT_WIDE
  2463. size_t __XL(wcsxfrm)(wchar_t *__restrict ws1, const wchar_t *__restrict ws2,
  2464. size_t n __LOCALE_PARAM )
  2465. {
  2466. col_state_t cs;
  2467. size_t count;
  2468. int pass;
  2469. if (!CUR_COLLATE->num_weights) { /* C locale */
  2470. return __wcslcpy(ws1, ws2, n);
  2471. }
  2472. #ifdef __UCLIBC_MJN3_ONLY__
  2473. #warning handle empty string as a special case
  2474. #endif
  2475. count = pass = 0;
  2476. do { /* loop through the weights levels */
  2477. init_col_state(&cs, ws2);
  2478. do { /* loop through the string */
  2479. next_weight(&cs, pass __LOCALE_ARG );
  2480. TRACE(("weight=%lu (%#lx)\n", (unsigned long) cs.weight, (unsigned long) cs.weight));
  2481. if (count < n) {
  2482. ws1[count] = cs.weight +1;
  2483. }
  2484. ++count;
  2485. TRACE(("--------------------------------------------\n"));
  2486. } while (cs.weight);
  2487. if (count <= n) { /* overwrite the trailing 0 end-of-pass marker */
  2488. ws1[count-1] = 1;
  2489. }
  2490. TRACE(("-------------------- pass %d --------------------\n", pass));
  2491. } while (++pass < CUR_COLLATE->num_weights);
  2492. if (count <= n) { /* oops... change it back */
  2493. ws1[count-1] = 0;
  2494. }
  2495. return count-1;
  2496. }
  2497. __XL_ALIAS(wcsxfrm)
  2498. #else /* WANT_WIDE */
  2499. static const unsigned long bound[] = {
  2500. 1UL << 7,
  2501. 1UL << 11,
  2502. 1UL << 16,
  2503. 1UL << 21,
  2504. 1UL << 26,
  2505. };
  2506. static unsigned char first[] = {
  2507. 0x0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
  2508. };
  2509. /* Use an extension of UTF-8 to store a 32 bit val in max 6 bytes. */
  2510. static size_t store(unsigned char *s, size_t count, size_t n, __uwchar_t weight)
  2511. {
  2512. int i, r;
  2513. i = 0;
  2514. do {
  2515. if (weight < bound[i]) {
  2516. break;
  2517. }
  2518. } while (++i < sizeof(bound)/sizeof(bound[0]));
  2519. r = i+1;
  2520. if (i + count < n) {
  2521. s += count;
  2522. s[0] = first[i];
  2523. while (i) {
  2524. s[i] = 0x80 | (weight & 0x3f);
  2525. weight >>= 6;
  2526. --i;
  2527. }
  2528. s[0] |= weight;
  2529. }
  2530. return r;
  2531. }
  2532. size_t __XL(strxfrm)(char *__restrict ws1, const char *__restrict ws2, size_t n
  2533. __LOCALE_PARAM )
  2534. {
  2535. col_state_t cs;
  2536. size_t count, inc;
  2537. int pass;
  2538. if (!CUR_COLLATE->num_weights) { /* C locale */
  2539. return strlcpy(ws1, ws2, n);
  2540. }
  2541. #ifdef __UCLIBC_MJN3_ONLY__
  2542. #warning handle empty string as a special case
  2543. #endif
  2544. inc = count = pass = 0;
  2545. do { /* loop through the weights levels */
  2546. init_col_state(&cs, ws2);
  2547. do { /* loop through the string */
  2548. next_weight(&cs, pass __LOCALE_ARG );
  2549. TRACE(("weight=%lu (%#lx)\n", (unsigned long) cs.weight, (unsigned long) cs.weight));
  2550. inc = store((unsigned char *)ws1, count, n, cs.weight + 1);
  2551. count += inc;
  2552. TRACE(("--------------------------------------------\n"));
  2553. } while (cs.weight);
  2554. /* overwrite the trailing 0 end-of-pass marker */
  2555. assert(inc == 1);
  2556. if (count <= n) {
  2557. ws1[count-1] = 1;
  2558. }
  2559. TRACE(("-------------------- pass %d --------------------\n", pass));
  2560. } while (++pass < CUR_COLLATE->num_weights);
  2561. if (count <= n) { /* oops... change it back */
  2562. ws1[count-1] = 0;
  2563. }
  2564. return count-1;
  2565. }
  2566. __XL_ALIAS(strxfrm)
  2567. #endif /* WANT_WIDE */
  2568. #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  2569. #endif /* defined(L_strxfrm) || defined(L_strxfrm_l) || defined(L_wcsxfrm) || defined(L_wcsxfrm_l) */
  2570. #endif /* __LOCALE_C_ONLY */
  2571. /**********************************************************************/