wstring.c 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984
  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 _GNU_SOURCE
  37. #include <string.h>
  38. #include <strings.h>
  39. #include <stdio.h>
  40. #include <limits.h>
  41. #include <ctype.h>
  42. #include <stdlib.h>
  43. #include <errno.h>
  44. #include <signal.h>
  45. #include <assert.h>
  46. #include <locale.h>
  47. #include <bits/uClibc_uintmaxtostr.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. #ifndef L_wcstok
  815. weak_alias(__strtok_r,strtok_r);
  816. #endif
  817. Wchar *Wstrtok_r(Wchar * __restrict s1, const Wchar * __restrict s2,
  818. Wchar ** __restrict next_start)
  819. {
  820. register Wchar *s;
  821. register Wchar *p;
  822. #if 1
  823. if (((s = s1) != NULL) || ((s = *next_start) != NULL)) {
  824. if (*(s += Wstrspn(s, s2))) {
  825. if ((p = Wstrpbrk(s, s2)) != NULL) {
  826. *p++ = 0;
  827. }
  828. } else {
  829. p = s = NULL;
  830. }
  831. *next_start = p;
  832. }
  833. return s;
  834. #else
  835. if (!(s = s1)) {
  836. s = *next_start;
  837. }
  838. if (s && *(s += Wstrspn(s, s2))) {
  839. if (*(p = s + Wstrcspn(s, s2))) {
  840. *p++ = 0;
  841. }
  842. *next_start = p;
  843. return s;
  844. }
  845. return NULL; /* TODO: set *next_start = NULL for safety? */
  846. #endif
  847. }
  848. #endif
  849. /**********************************************************************/
  850. /* #ifdef L_wcstok */
  851. /* #define L_strtok */
  852. /* #define Wstrtok wcstok */
  853. /* #define Wstrtok_r wcstok_r */
  854. /* #else */
  855. /* #define Wstrtok strtok */
  856. /* #define Wstrtok_r strtok_r */
  857. /* #endif */
  858. #ifdef L_strtok
  859. #define Wstrtok strtok
  860. #define Wstrtok_r __strtok_r
  861. Wchar *Wstrtok(Wchar * __restrict s1, const Wchar * __restrict s2)
  862. {
  863. static Wchar *next_start; /* Initialized to 0 since in bss. */
  864. return Wstrtok_r(s1, s2, &next_start);
  865. }
  866. #endif
  867. /**********************************************************************/
  868. #ifdef L_wmemset
  869. #define L_memset
  870. #define Wmemset wmemset
  871. #else
  872. #define Wmemset memset
  873. #endif
  874. #ifdef L_memset
  875. Wvoid *Wmemset(Wvoid *s, Wint c, size_t n)
  876. {
  877. register Wuchar *p = (Wuchar *) s;
  878. #ifdef __BCC__
  879. /* bcc can optimize the counter if it thinks it is a pointer... */
  880. register const char *np = (const char *) n;
  881. #else
  882. #define np n
  883. #endif
  884. while (np) {
  885. *p++ = (Wuchar) c;
  886. --np;
  887. }
  888. return s;
  889. }
  890. #undef np
  891. #endif
  892. /**********************************************************************/
  893. #ifdef L_wcslen
  894. #define L_strlen
  895. #define Wstrlen wcslen
  896. #else
  897. #define Wstrlen strlen
  898. #endif
  899. #ifdef L_strlen
  900. size_t Wstrlen(const Wchar *s)
  901. {
  902. register const Wchar *p;
  903. for (p=s ; *p ; p++);
  904. return p - s;
  905. }
  906. #endif
  907. /**********************************************************************/
  908. /* ANSI/ISO end here */
  909. /**********************************************************************/
  910. #ifdef L_ffs
  911. int ffs(int i)
  912. {
  913. #if 1
  914. /* inlined binary search method */
  915. char n = 1;
  916. #if UINT_MAX == 0xffffU
  917. /* nothing to do here -- just trying to avoiding possible problems */
  918. #elif UINT_MAX == 0xffffffffU
  919. if (!(i & 0xffff)) {
  920. n += 16;
  921. i >>= 16;
  922. }
  923. #else
  924. #error ffs needs rewriting!
  925. #endif
  926. if (!(i & 0xff)) {
  927. n += 8;
  928. i >>= 8;
  929. }
  930. if (!(i & 0x0f)) {
  931. n += 4;
  932. i >>= 4;
  933. }
  934. if (!(i & 0x03)) {
  935. n += 2;
  936. i >>= 2;
  937. }
  938. return (i) ? (n + ((i+1) & 0x01)) : 0;
  939. #else
  940. /* linear search -- slow, but small */
  941. int n;
  942. for (n = 0 ; i ; ++n) {
  943. i >>= 1;
  944. }
  945. return n;
  946. #endif
  947. }
  948. #endif
  949. /**********************************************************************/
  950. #if defined(L_strcasecmp) || defined(L_strcasecmp_l) || defined(L_wcscasecmp) || defined(L_wcscasecmp_l)
  951. #if defined(L_wcscasecmp) || defined(L_wcscasecmp_l)
  952. #define strcasecmp wcscasecmp
  953. #define strcasecmp_l wcscasecmp_l
  954. #define __strcasecmp_l __wcscasecmp_l
  955. #ifdef __UCLIBC_DO_XLOCALE
  956. #define TOLOWER(C) __towlower_l((C), locale_arg)
  957. #else
  958. #define TOLOWER(C) towlower((C))
  959. #endif
  960. #else /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */
  961. #ifdef __UCLIBC_DO_XLOCALE
  962. #define TOLOWER(C) __tolower_l((C), locale_arg)
  963. #else
  964. #define TOLOWER(C) tolower((C))
  965. #endif
  966. #endif /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */
  967. #if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
  968. int strcasecmp(register const Wchar *s1, register const Wchar *s2)
  969. {
  970. return __strcasecmp_l(s1, s2, __UCLIBC_CURLOCALE);
  971. }
  972. #else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  973. int __XL(strcasecmp)(register const Wchar *s1, register const Wchar *s2
  974. __LOCALE_PARAM )
  975. {
  976. #ifdef WANT_WIDE
  977. while ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2))) {
  978. if (!*s1++) {
  979. return 0;
  980. }
  981. ++s2;
  982. }
  983. return (((Wuchar)TOLOWER(*s1)) < ((Wuchar)TOLOWER(*s2))) ? -1 : 1;
  984. /* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
  985. #else
  986. int r = 0;
  987. while ( ((s1 == s2) ||
  988. !(r = ((int)( TOLOWER(*((Wuchar *)s1))))
  989. - TOLOWER(*((Wuchar *)s2))))
  990. && (++s2, *s1++));
  991. return r;
  992. #endif
  993. }
  994. __XL_ALIAS(strcasecmp)
  995. #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  996. #endif
  997. /**********************************************************************/
  998. #if defined(L_strncasecmp) || defined(L_strncasecmp_l) || defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l)
  999. #if defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l)
  1000. #define strncasecmp wcsncasecmp
  1001. #define strncasecmp_l wcsncasecmp_l
  1002. #define __strncasecmp_l __wcsncasecmp_l
  1003. #ifdef __UCLIBC_DO_XLOCALE
  1004. #define TOLOWER(C) __towlower_l((C), locale_arg)
  1005. #else
  1006. #define TOLOWER(C) towlower((C))
  1007. #endif
  1008. #else /* defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) */
  1009. #ifdef __UCLIBC_DO_XLOCALE
  1010. #define TOLOWER(C) __tolower_l((C), locale_arg)
  1011. #else
  1012. #define TOLOWER(C) tolower((C))
  1013. #endif
  1014. #endif /* defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) */
  1015. #if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
  1016. int strncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n)
  1017. {
  1018. return __strncasecmp_l(s1, s2, n, __UCLIBC_CURLOCALE);
  1019. }
  1020. #else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  1021. int __XL(strncasecmp)(register const Wchar *s1, register const Wchar *s2,
  1022. size_t n __LOCALE_PARAM )
  1023. {
  1024. #ifdef WANT_WIDE
  1025. while (n && ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2)))) {
  1026. if (!*s1++) {
  1027. return 0;
  1028. }
  1029. ++s2;
  1030. --n;
  1031. }
  1032. return (n == 0)
  1033. ? 0
  1034. : ((((Wuchar)TOLOWER(*s1)) < ((Wuchar)TOLOWER(*s2))) ? -1 : 1);
  1035. /* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
  1036. #else
  1037. int r = 0;
  1038. while ( n
  1039. && ((s1 == s2) ||
  1040. !(r = ((int)( TOLOWER(*((unsigned char *)s1))))
  1041. - TOLOWER(*((unsigned char *)s2))))
  1042. && (--n, ++s2, *s1++));
  1043. return r;
  1044. #endif
  1045. }
  1046. __XL_ALIAS(strncasecmp)
  1047. #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  1048. #endif
  1049. /**********************************************************************/
  1050. #ifdef L_wcsnlen
  1051. #define L_strnlen
  1052. #define Wstrnlen wcsnlen
  1053. #else
  1054. #define Wstrnlen strnlen
  1055. #endif
  1056. #ifdef L_strnlen
  1057. size_t Wstrnlen(const Wchar *s, size_t max)
  1058. {
  1059. register const Wchar *p = s;
  1060. #ifdef __BCC__
  1061. /* bcc can optimize the counter if it thinks it is a pointer... */
  1062. register const char *maxp = (const char *) max;
  1063. #else
  1064. #define maxp max
  1065. #endif
  1066. while (maxp && *p) {
  1067. ++p;
  1068. --maxp;
  1069. }
  1070. return p - s;
  1071. }
  1072. #undef maxp
  1073. #endif
  1074. /**********************************************************************/
  1075. /* No wide analog. */
  1076. #ifdef L_memccpy
  1077. void *memccpy(void * __restrict s1, const void * __restrict s2, int c, size_t n)
  1078. {
  1079. register char *r1 = s1;
  1080. register const char *r2 = s2;
  1081. while (n-- && (((unsigned char)(*r1++ = *r2++)) != ((unsigned char) c)));
  1082. return (n == (size_t) -1) ? NULL : r1;
  1083. }
  1084. #endif
  1085. /**********************************************************************/
  1086. #undef Wstrlen
  1087. #undef Wstrcpy
  1088. #ifdef L_wcsdup
  1089. #define L_strdup
  1090. #define Wstrdup wcsdup
  1091. #define Wstrlen wcslen
  1092. #define Wstrcpy wcscpy
  1093. #else
  1094. #define Wstrdup strdup
  1095. #define Wstrlen strlen
  1096. #define Wstrcpy strcpy
  1097. #endif
  1098. #ifdef L_strdup
  1099. Wchar *Wstrdup(register const Wchar *s1)
  1100. {
  1101. register Wchar *s;
  1102. if ((s = malloc((Wstrlen(s1) + 1) * sizeof(Wchar))) != NULL) {
  1103. Wstrcpy(s, s1);
  1104. }
  1105. return s;
  1106. }
  1107. #endif
  1108. /**********************************************************************/
  1109. #ifdef L_strerror
  1110. char *strerror(int errnum)
  1111. {
  1112. static char buf[_STRERROR_BUFSIZE];
  1113. __xpg_strerror_r(errnum, buf, sizeof(buf));
  1114. return buf;
  1115. }
  1116. #endif
  1117. /**********************************************************************/
  1118. /* SUSv3 functions. */
  1119. /**********************************************************************/
  1120. #ifdef L___xpg_strerror_r
  1121. #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
  1122. #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
  1123. static const unsigned char estridx[] = {
  1124. 0, /* success is always 0 */
  1125. EPERM,
  1126. ENOENT,
  1127. ESRCH,
  1128. EINTR,
  1129. EIO,
  1130. ENXIO,
  1131. E2BIG,
  1132. ENOEXEC,
  1133. EBADF,
  1134. ECHILD,
  1135. EAGAIN,
  1136. ENOMEM,
  1137. EACCES,
  1138. EFAULT,
  1139. ENOTBLK,
  1140. EBUSY,
  1141. EEXIST,
  1142. EXDEV,
  1143. ENODEV,
  1144. ENOTDIR,
  1145. EISDIR,
  1146. EINVAL,
  1147. ENFILE,
  1148. EMFILE,
  1149. ENOTTY,
  1150. ETXTBSY,
  1151. EFBIG,
  1152. ENOSPC,
  1153. ESPIPE,
  1154. EROFS,
  1155. EMLINK,
  1156. EPIPE,
  1157. EDOM,
  1158. ERANGE,
  1159. EDEADLK,
  1160. ENAMETOOLONG,
  1161. ENOLCK,
  1162. ENOSYS,
  1163. ENOTEMPTY,
  1164. ELOOP,
  1165. 0,
  1166. ENOMSG,
  1167. EIDRM,
  1168. ECHRNG,
  1169. EL2NSYNC,
  1170. EL3HLT,
  1171. EL3RST,
  1172. ELNRNG,
  1173. EUNATCH,
  1174. ENOCSI,
  1175. EL2HLT,
  1176. EBADE,
  1177. EBADR,
  1178. EXFULL,
  1179. ENOANO,
  1180. EBADRQC,
  1181. EBADSLT,
  1182. 0,
  1183. EBFONT,
  1184. ENOSTR,
  1185. ENODATA,
  1186. ETIME,
  1187. ENOSR,
  1188. ENONET,
  1189. ENOPKG,
  1190. EREMOTE,
  1191. ENOLINK,
  1192. EADV,
  1193. ESRMNT,
  1194. ECOMM,
  1195. EPROTO,
  1196. EMULTIHOP,
  1197. EDOTDOT,
  1198. EBADMSG,
  1199. EOVERFLOW,
  1200. ENOTUNIQ,
  1201. EBADFD,
  1202. EREMCHG,
  1203. ELIBACC,
  1204. ELIBBAD,
  1205. ELIBSCN,
  1206. ELIBMAX,
  1207. ELIBEXEC,
  1208. EILSEQ,
  1209. ERESTART,
  1210. ESTRPIPE,
  1211. EUSERS,
  1212. ENOTSOCK,
  1213. EDESTADDRREQ,
  1214. EMSGSIZE,
  1215. EPROTOTYPE,
  1216. ENOPROTOOPT,
  1217. EPROTONOSUPPORT,
  1218. ESOCKTNOSUPPORT,
  1219. EOPNOTSUPP,
  1220. EPFNOSUPPORT,
  1221. EAFNOSUPPORT,
  1222. EADDRINUSE,
  1223. EADDRNOTAVAIL,
  1224. ENETDOWN,
  1225. ENETUNREACH,
  1226. ENETRESET,
  1227. ECONNABORTED,
  1228. ECONNRESET,
  1229. ENOBUFS,
  1230. EISCONN,
  1231. ENOTCONN,
  1232. ESHUTDOWN,
  1233. ETOOMANYREFS,
  1234. ETIMEDOUT,
  1235. ECONNREFUSED,
  1236. EHOSTDOWN,
  1237. EHOSTUNREACH,
  1238. EALREADY,
  1239. EINPROGRESS,
  1240. ESTALE,
  1241. EUCLEAN,
  1242. ENOTNAM,
  1243. ENAVAIL,
  1244. EISNAM,
  1245. EREMOTEIO,
  1246. #ifdef __mips__
  1247. 0, /* mips has an outrageous value for this... */
  1248. #else
  1249. EDQUOT,
  1250. #endif
  1251. ENOMEDIUM,
  1252. EMEDIUMTYPE,
  1253. #if defined(__mips__) || defined(__sparc__)
  1254. EDEADLOCK,
  1255. #endif
  1256. };
  1257. #endif
  1258. int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
  1259. {
  1260. register char *s;
  1261. int i, retval;
  1262. char buf[_STRERROR_BUFSIZE];
  1263. static const char unknown[] = {
  1264. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
  1265. };
  1266. retval = EINVAL;
  1267. #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
  1268. #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
  1269. /* Need to translate errno to string index. */
  1270. for (i = 0 ; i < sizeof(estridx)/sizeof(estridx[0]) ; i++) {
  1271. if (estridx[i] == errnum) {
  1272. goto GOT_ESTRIDX;
  1273. }
  1274. }
  1275. i = INT_MAX; /* Failed, but may need to check mips special case. */
  1276. #ifdef __mips__
  1277. if (errnum == EDQUOT) { /* Deal with large EDQUOT value on mips */
  1278. i = 122;
  1279. }
  1280. #endif /* __mips__ */
  1281. GOT_ESTRIDX:
  1282. #else
  1283. /* No errno to string index translation needed. */
  1284. i = errnum;
  1285. #endif
  1286. if (((unsigned int) i) < _SYS_NERR) {
  1287. /* Trade time for space. This function should rarely be called
  1288. * so rather than keeping an array of pointers for the different
  1289. * messages, just run through the buffer until we find the
  1290. * correct string. */
  1291. for (s = (char *) _string_syserrmsgs ; i ; ++s) {
  1292. if (!*s) {
  1293. --i;
  1294. }
  1295. }
  1296. if (*s) { /* Make sure we have an actual message. */
  1297. retval = 0;
  1298. goto GOT_MESG;
  1299. }
  1300. }
  1301. #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  1302. s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
  1303. memcpy(s, unknown, sizeof(unknown));
  1304. GOT_MESG:
  1305. if (!strerrbuf) { /* SUSv3 */
  1306. buflen = 0;
  1307. }
  1308. i = strlen(s) + 1;
  1309. if (i > buflen) {
  1310. i = buflen;
  1311. retval = ERANGE;
  1312. }
  1313. if (i) {
  1314. memcpy(strerrbuf, s, i);
  1315. strerrbuf[i-1] = 0; /* In case buf was too small. */
  1316. }
  1317. if (retval) {
  1318. __set_errno(retval);
  1319. }
  1320. return retval;
  1321. }
  1322. #else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  1323. int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
  1324. {
  1325. register char *s;
  1326. int i, retval;
  1327. char buf[_STRERROR_BUFSIZE];
  1328. static const char unknown[] = {
  1329. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
  1330. };
  1331. s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
  1332. memcpy(s, unknown, sizeof(unknown));
  1333. if (!strerrbuf) { /* SUSv3 */
  1334. buflen = 0;
  1335. }
  1336. retval = EINVAL;
  1337. i = buf + sizeof(buf) - s;
  1338. if (i > buflen) {
  1339. i = buflen;
  1340. retval = ERANGE;
  1341. }
  1342. if (i) {
  1343. memcpy(strerrbuf, s, i);
  1344. strerrbuf[i-1] = 0; /* In case buf was too small. */
  1345. }
  1346. __set_errno(retval);
  1347. return retval;
  1348. }
  1349. #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  1350. #endif
  1351. /**********************************************************************/
  1352. /* GNU extension functions. */
  1353. /**********************************************************************/
  1354. #ifdef L___glibc_strerror_r
  1355. char *__glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen)
  1356. {
  1357. __xpg_strerror_r(errnum, strerrbuf, buflen);
  1358. return strerrbuf;
  1359. }
  1360. weak_alias(__glibc_strerror_r,__strerror_r);
  1361. #endif
  1362. /**********************************************************************/
  1363. #ifdef L_memmem
  1364. void *memmem(const void *haystack, size_t haystacklen,
  1365. const void *needle, size_t needlelen)
  1366. {
  1367. register const char *ph;
  1368. register const char *pn;
  1369. const char *plast;
  1370. size_t n;
  1371. if (needlelen == 0) {
  1372. return (void *) haystack;
  1373. }
  1374. if (haystacklen >= needlelen) {
  1375. ph = (const char *) haystack;
  1376. pn = (const char *) needle;
  1377. plast = ph + (haystacklen - needlelen);
  1378. do {
  1379. n = 0;
  1380. while (ph[n] == pn[n]) {
  1381. if (++n == needlelen) {
  1382. return (void *) ph;
  1383. }
  1384. }
  1385. } while (++ph <= plast);
  1386. }
  1387. return NULL;
  1388. }
  1389. #endif
  1390. /**********************************************************************/
  1391. #ifdef L_wmempcpy
  1392. #define L_mempcpy
  1393. #define Wmempcpy wmempcpy
  1394. #else
  1395. #define Wmempcpy __mempcpy
  1396. #endif
  1397. #ifdef L_mempcpy
  1398. #ifndef L_wmempcpy
  1399. weak_alias(__mempcpy,mempcpy);
  1400. #endif
  1401. Wvoid *Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
  1402. {
  1403. register Wchar *r1 = s1;
  1404. register const Wchar *r2 = s2;
  1405. #ifdef __BCC__
  1406. while (n--) {
  1407. *r1++ = *r2++;
  1408. }
  1409. #else
  1410. while (n) {
  1411. *r1++ = *r2++;
  1412. --n;
  1413. }
  1414. #endif
  1415. return r1;
  1416. }
  1417. #endif
  1418. /**********************************************************************/
  1419. #ifdef L_memrchr
  1420. void *memrchr(const void *s, int c, size_t n)
  1421. {
  1422. register const unsigned char *r;
  1423. #ifdef __BCC__
  1424. /* bcc can optimize the counter if it thinks it is a pointer... */
  1425. register const char *np = (const char *) n;
  1426. #else
  1427. #define np n
  1428. #endif
  1429. r = ((unsigned char *)s) + ((size_t) np);
  1430. while (np) {
  1431. if (*--r == ((unsigned char)c)) {
  1432. return (void *) r; /* silence the warning */
  1433. }
  1434. --np;
  1435. }
  1436. return NULL;
  1437. }
  1438. #undef np
  1439. #endif
  1440. /**********************************************************************/
  1441. #ifdef L_wcpcpy
  1442. #define L_stpcpy
  1443. #define Wstpcpy wcpcpy
  1444. #else
  1445. #define Wstpcpy stpcpy
  1446. #endif
  1447. #ifdef L_stpcpy
  1448. Wchar *Wstpcpy(register Wchar * __restrict s1, const Wchar * __restrict s2)
  1449. {
  1450. #ifdef __BCC__
  1451. do {
  1452. *s1 = *s2++;
  1453. } while (*s1++ != 0);
  1454. #else
  1455. while ( (*s1++ = *s2++) != 0 );
  1456. #endif
  1457. return s1 - 1;
  1458. }
  1459. #endif
  1460. /**********************************************************************/
  1461. #ifdef L_wcpncpy
  1462. #define L_stpncpy
  1463. #define Wstpncpy wcpncpy
  1464. #else
  1465. #define Wstpncpy stpncpy
  1466. #endif
  1467. #ifdef L_stpncpy
  1468. Wchar *Wstpncpy(register Wchar * __restrict s1,
  1469. register const Wchar * __restrict s2,
  1470. size_t n)
  1471. {
  1472. Wchar *s = s1;
  1473. const Wchar *p = s2;
  1474. #ifdef __BCC__
  1475. while (n--) {
  1476. if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
  1477. ++s;
  1478. }
  1479. return s1 + (s2 - p);
  1480. #else
  1481. while (n) {
  1482. if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
  1483. ++s;
  1484. --n;
  1485. }
  1486. return s1 + (s2 - p);
  1487. #endif
  1488. }
  1489. #endif
  1490. /**********************************************************************/
  1491. #ifdef L_bzero
  1492. weak_alias(__bzero,bzero);
  1493. void __bzero(void *s, size_t n)
  1494. {
  1495. register unsigned char *p = s;
  1496. #ifdef __BCC__
  1497. /* bcc can optimize the counter if it thinks it is a pointer... */
  1498. register const char *np = (const char *) n;
  1499. #else
  1500. #define np n
  1501. #endif
  1502. while (np) {
  1503. *p++ = 0;
  1504. --np;
  1505. }
  1506. }
  1507. #undef np
  1508. #endif
  1509. /**********************************************************************/
  1510. #ifdef L_bcopy
  1511. void bcopy(const void *s2, void *s1, size_t n)
  1512. {
  1513. #if 1
  1514. memmove(s1, s2, n);
  1515. #else
  1516. #ifdef __BCC__
  1517. register char *s;
  1518. register const char *p;
  1519. s = s1;
  1520. p = s2;
  1521. if (p >= s) {
  1522. while (n--) {
  1523. *s++ = *p++;
  1524. }
  1525. } else {
  1526. s += n;
  1527. p += n;
  1528. while (n--) {
  1529. *--s = *--p;
  1530. }
  1531. }
  1532. #else
  1533. register char *s;
  1534. register const char *p;
  1535. s = s1;
  1536. p = s2;
  1537. if (p >= s) {
  1538. while (n) {
  1539. *s++ = *p++;
  1540. --n;
  1541. }
  1542. } else {
  1543. while (n) {
  1544. --n;
  1545. s[n] = p[n];
  1546. }
  1547. }
  1548. #endif
  1549. #endif
  1550. }
  1551. #endif
  1552. /**********************************************************************/
  1553. #ifdef L_strcasestr
  1554. char *strcasestr(const char *s1, const char *s2)
  1555. {
  1556. register const char *s = s1;
  1557. register const char *p = s2;
  1558. #if 1
  1559. do {
  1560. if (!*p) {
  1561. return (char *) s1;;
  1562. }
  1563. if ((*p == *s)
  1564. || (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
  1565. ) {
  1566. ++p;
  1567. ++s;
  1568. } else {
  1569. p = s2;
  1570. if (!*s) {
  1571. return NULL;
  1572. }
  1573. s = ++s1;
  1574. }
  1575. } while (1);
  1576. #else
  1577. while (*p && *s) {
  1578. if ((*p == *s)
  1579. || (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
  1580. ) {
  1581. ++p;
  1582. ++s;
  1583. } else {
  1584. p = s2;
  1585. s = ++s1;
  1586. }
  1587. }
  1588. return (*p) ? NULL : (char *) s1;
  1589. #endif
  1590. }
  1591. #endif
  1592. /**********************************************************************/
  1593. #ifdef L_strndup
  1594. char *strndup(register const char *s1, size_t n)
  1595. {
  1596. register char *s;
  1597. n = strnlen(s1,n); /* Avoid problems if s1 not nul-terminated. */
  1598. if ((s = malloc(n + 1)) != NULL) {
  1599. memcpy(s, s1, n);
  1600. s[n] = 0;
  1601. }
  1602. return s;
  1603. }
  1604. #endif
  1605. /**********************************************************************/
  1606. #ifdef L_strsep
  1607. char *strsep(char ** __restrict s1, const char * __restrict s2)
  1608. {
  1609. register char *s = *s1;
  1610. register char *p;
  1611. #if 1
  1612. p = NULL;
  1613. if (s && *s && (p = strpbrk(s, s2))) {
  1614. *p++ = 0;
  1615. }
  1616. #else
  1617. if (s && *s && *(p = s + strcspn(s, s2))) {
  1618. *p++ = 0;
  1619. } else {
  1620. p = NULL;
  1621. }
  1622. #endif
  1623. *s1 = p;
  1624. return s;
  1625. }
  1626. #endif
  1627. /**********************************************************************/
  1628. #ifdef L_wcschrnul
  1629. #define L_strchrnul
  1630. #define __Wstrchrnul __wcschrnul
  1631. #define Wstrchrnul wcschrnul
  1632. #else
  1633. #define __Wstrchrnul __strchrnul
  1634. #define Wstrchrnul strchrnul
  1635. #endif
  1636. #ifdef L_strchrnul
  1637. extern Wchar *__Wstrchrnul(register const Wchar *s, Wint c);
  1638. weak_alias(__Wstrchrnul, Wstrchrnul);
  1639. Wchar *__Wstrchrnul(register const Wchar *s, Wint c)
  1640. {
  1641. --s;
  1642. while (*++s && (*s != ((Wchar)c)));
  1643. return (Wchar *) s;
  1644. }
  1645. #endif
  1646. /**********************************************************************/
  1647. #ifdef L_rawmemchr
  1648. void *rawmemchr(const void *s, int c)
  1649. {
  1650. register const unsigned char *r = s;
  1651. while (*r != ((unsigned char)c)) ++r;
  1652. return (void *) r; /* silence the warning */
  1653. }
  1654. #endif
  1655. /**********************************************************************/
  1656. #ifdef L_basename
  1657. char *basename(const char *path)
  1658. {
  1659. register const char *s;
  1660. register const char *p;
  1661. p = s = path;
  1662. while (*s) {
  1663. if (*s++ == '/') {
  1664. p = s;
  1665. }
  1666. }
  1667. return (char *) p;
  1668. }
  1669. #endif
  1670. /**********************************************************************/
  1671. #ifdef L___xpg_basename
  1672. char *__xpg_basename(register char *path)
  1673. {
  1674. static const char null_or_empty[] = ".";
  1675. char *first;
  1676. register char *last;
  1677. first = (char *) null_or_empty;
  1678. if (path && *path) {
  1679. first = path;
  1680. last = path - 1;
  1681. do {
  1682. if ((*path != '/') && (path > ++last)) {
  1683. last = first = path;
  1684. }
  1685. } while (*++path);
  1686. if (*first == '/') {
  1687. last = first;
  1688. }
  1689. last[1] = 0;
  1690. }
  1691. return first;
  1692. }
  1693. #endif
  1694. /**********************************************************************/
  1695. #ifdef L_dirname
  1696. char *dirname(char *path)
  1697. {
  1698. static const char null_or_empty_or_noslash[] = ".";
  1699. register char *s;
  1700. register char *last;
  1701. char *first;
  1702. last = s = path;
  1703. if (s != NULL) {
  1704. LOOP:
  1705. while (*s && (*s != '/')) ++s;
  1706. first = s;
  1707. while (*s == '/') ++s;
  1708. if (*s) {
  1709. last = first;
  1710. goto LOOP;
  1711. }
  1712. if (last == path) {
  1713. if (*last != '/') {
  1714. goto DOT;
  1715. }
  1716. if ((*++last == '/') && (last[1] == 0)) {
  1717. ++last;
  1718. }
  1719. }
  1720. *last = 0;
  1721. return path;
  1722. }
  1723. DOT:
  1724. return (char *) null_or_empty_or_noslash;
  1725. }
  1726. #endif
  1727. /**********************************************************************/
  1728. #ifdef L_strlcat
  1729. /* OpenBSD function:
  1730. * Append at most n-1-strlen(dst) chars from src to dst and nul-terminate dst.
  1731. * Returns strlen(src) + strlen({original} dst), so truncation occurred if the
  1732. * return val is >= n.
  1733. * Note: If dst doesn't contain a nul in the first n chars, strlen(dst) is
  1734. * taken as n. */
  1735. size_t strlcat(register char *__restrict dst,
  1736. register const char *__restrict src,
  1737. size_t n)
  1738. {
  1739. size_t len;
  1740. char dummy[1];
  1741. len = 0;
  1742. while (1) {
  1743. if (len >= n) {
  1744. dst = dummy;
  1745. break;
  1746. }
  1747. if (!*dst) {
  1748. break;
  1749. }
  1750. ++dst;
  1751. ++len;
  1752. }
  1753. while ((*dst = *src) != 0) {
  1754. if (++len < n) {
  1755. ++dst;
  1756. }
  1757. ++src;
  1758. }
  1759. return len;
  1760. }
  1761. #endif
  1762. /**********************************************************************/
  1763. #ifdef WANT_WIDE
  1764. extern size_t __wcslcpy(wchar_t *__restrict dst,
  1765. const wchar_t *__restrict src,
  1766. size_t n);
  1767. #endif
  1768. #ifdef L___wcslcpy
  1769. #define L_strlcpy
  1770. #define Wstrlcpy __wcslcpy
  1771. #ifdef __LOCALE_C_ONLY
  1772. weak_alias(__wcslcpy,wcsxfrm);
  1773. #endif
  1774. #endif
  1775. #ifdef L_strlcpy
  1776. #ifndef L___wcslcpy
  1777. #define Wstrlcpy strlcpy
  1778. #ifdef __LOCALE_C_ONLY
  1779. weak_alias(strlcpy,strxfrm);
  1780. #endif
  1781. #endif
  1782. /* OpenBSD function:
  1783. * Copy at most n-1 chars from src to dst and nul-terminate dst.
  1784. * Returns strlen(src), so truncation occurred if the return value is >= n. */
  1785. size_t Wstrlcpy(register Wchar *__restrict dst,
  1786. register const Wchar *__restrict src,
  1787. size_t n)
  1788. {
  1789. const Wchar *src0 = src;
  1790. Wchar dummy[1];
  1791. if (!n) {
  1792. dst = dummy;
  1793. } else {
  1794. --n;
  1795. }
  1796. while ((*dst = *src) != 0) {
  1797. if (n) {
  1798. --n;
  1799. ++dst;
  1800. }
  1801. ++src;
  1802. }
  1803. return src - src0;
  1804. }
  1805. #endif
  1806. /**********************************************************************/
  1807. #if defined(L__string_syssigmsgs) && defined(__UCLIBC_HAS_SIGNUM_MESSAGES__)
  1808. const char _string_syssigmsgs[] = {
  1809. /* 0: 0, 1 */ "\0"
  1810. /* 1: 1, 7 */ "Hangup\0"
  1811. /* 2: 8, 10 */ "Interrupt\0"
  1812. /* 3: 18, 5 */ "Quit\0"
  1813. /* 4: 23, 20 */ "Illegal instruction\0"
  1814. /* 5: 43, 22 */ "Trace/breakpoint trap\0"
  1815. /* 6: 65, 8 */ "Aborted\0"
  1816. /* 7: 73, 10 */ "Bus error\0"
  1817. /* 8: 83, 25 */ "Floating point exception\0"
  1818. /* 9: 108, 7 */ "Killed\0"
  1819. /* 10: 115, 22 */ "User defined signal 1\0"
  1820. /* 11: 137, 19 */ "Segmentation fault\0"
  1821. /* 12: 156, 22 */ "User defined signal 2\0"
  1822. /* 13: 178, 12 */ "Broken pipe\0"
  1823. /* 14: 190, 12 */ "Alarm clock\0"
  1824. /* 15: 202, 11 */ "Terminated\0"
  1825. /* 16: 213, 12 */ "Stack fault\0"
  1826. /* 17: 225, 13 */ "Child exited\0"
  1827. /* 18: 238, 10 */ "Continued\0"
  1828. /* 19: 248, 17 */ "Stopped (signal)\0"
  1829. /* 20: 265, 8 */ "Stopped\0"
  1830. /* 21: 273, 20 */ "Stopped (tty input)\0"
  1831. /* 22: 293, 21 */ "Stopped (tty output)\0"
  1832. /* 23: 314, 21 */ "Urgent I/O condition\0"
  1833. /* 24: 335, 24 */ "CPU time limit exceeded\0"
  1834. /* 25: 359, 25 */ "File size limit exceeded\0"
  1835. /* 26: 384, 22 */ "Virtual timer expired\0"
  1836. /* 27: 406, 24 */ "Profiling timer expired\0"
  1837. /* 28: 430, 15 */ "Window changed\0"
  1838. /* 29: 445, 13 */ "I/O possible\0"
  1839. /* 30: 458, 14 */ "Power failure\0"
  1840. /* 31: 472, 16 */ "Bad system call"
  1841. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1842. /* 32: 488, 9 */ "\0EMT trap"
  1843. #endif
  1844. };
  1845. #endif
  1846. /**********************************************************************/
  1847. #if defined(L_sys_siglist) && defined(__UCLIBC_HAS_SYS_SIGLIST__)
  1848. const char *const sys_siglist[_NSIG] = {
  1849. [0] = NULL,
  1850. [SIGHUP] = _string_syssigmsgs + 1,
  1851. [SIGINT] = _string_syssigmsgs + 8,
  1852. [SIGQUIT] = _string_syssigmsgs + 18,
  1853. [SIGILL] = _string_syssigmsgs + 23,
  1854. [SIGTRAP] = _string_syssigmsgs + 43,
  1855. [SIGABRT] = _string_syssigmsgs + 65,
  1856. [SIGBUS] = _string_syssigmsgs + 73,
  1857. [SIGFPE] = _string_syssigmsgs + 83,
  1858. [SIGKILL] = _string_syssigmsgs + 108,
  1859. [SIGUSR1] = _string_syssigmsgs + 115,
  1860. [SIGSEGV] = _string_syssigmsgs + 137,
  1861. [SIGUSR2] = _string_syssigmsgs + 156,
  1862. [SIGPIPE] = _string_syssigmsgs + 178,
  1863. [SIGALRM] = _string_syssigmsgs + 190,
  1864. [SIGTERM] = _string_syssigmsgs + 202,
  1865. #if !(defined(__alpha__) || defined(__mips__) || defined(__sparc__))
  1866. [SIGSTKFLT] = _string_syssigmsgs + 213,
  1867. #endif
  1868. [SIGCHLD] = _string_syssigmsgs + 225,
  1869. [SIGCONT] = _string_syssigmsgs + 238,
  1870. [SIGSTOP] = _string_syssigmsgs + 248,
  1871. [SIGTSTP] = _string_syssigmsgs + 265,
  1872. [SIGTTIN] = _string_syssigmsgs + 273,
  1873. [SIGTTOU] = _string_syssigmsgs + 293,
  1874. [SIGURG] = _string_syssigmsgs + 314,
  1875. [SIGXCPU] = _string_syssigmsgs + 335,
  1876. [SIGXFSZ] = _string_syssigmsgs + 359,
  1877. [SIGVTALRM] = _string_syssigmsgs + 384,
  1878. [SIGPROF] = _string_syssigmsgs + 406,
  1879. [SIGWINCH] = _string_syssigmsgs + 430,
  1880. [SIGIO] = _string_syssigmsgs + 445,
  1881. [SIGPWR] = _string_syssigmsgs + 458,
  1882. [SIGSYS] = _string_syssigmsgs + 472,
  1883. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1884. [SIGEMT] = _string_syssigmsgs + 488,
  1885. #endif
  1886. };
  1887. #endif
  1888. /**********************************************************************/
  1889. #ifdef L_strsignal
  1890. /* TODO: make a threadsafe version? */
  1891. #ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__
  1892. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1893. static const unsigned char sstridx[] = {
  1894. 0,
  1895. SIGHUP,
  1896. SIGINT,
  1897. SIGQUIT,
  1898. SIGILL,
  1899. SIGTRAP,
  1900. SIGIOT,
  1901. SIGBUS,
  1902. SIGFPE,
  1903. SIGKILL,
  1904. SIGUSR1,
  1905. SIGSEGV,
  1906. SIGUSR2,
  1907. SIGPIPE,
  1908. SIGALRM,
  1909. SIGTERM,
  1910. #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
  1911. 0,
  1912. #else
  1913. SIGSTKFLT,
  1914. #endif
  1915. SIGCHLD,
  1916. SIGCONT,
  1917. SIGSTOP,
  1918. SIGTSTP,
  1919. SIGTTIN,
  1920. SIGTTOU,
  1921. SIGURG,
  1922. SIGXCPU,
  1923. SIGXFSZ,
  1924. SIGVTALRM,
  1925. SIGPROF,
  1926. SIGWINCH,
  1927. SIGIO,
  1928. SIGPWR,
  1929. SIGSYS,
  1930. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1931. SIGEMT,
  1932. #endif
  1933. };
  1934. #endif
  1935. char *strsignal(int signum)
  1936. {
  1937. register char *s;
  1938. int i;
  1939. static char buf[_STRSIGNAL_BUFSIZE];
  1940. static const char unknown[] = {
  1941. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' '
  1942. };
  1943. #if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
  1944. /* Need to translate signum to string index. */
  1945. for (i = 0 ; i < sizeof(sstridx)/sizeof(sstridx[0]) ; i++) {
  1946. if (sstridx[i] == signum) {
  1947. goto GOT_SSTRIDX;
  1948. }
  1949. }
  1950. i = INT_MAX; /* Failed. */
  1951. GOT_SSTRIDX:
  1952. #else
  1953. /* No signum to string index translation needed. */
  1954. i = signum;
  1955. #endif
  1956. if (((unsigned int) signum) < _SYS_NSIG) {
  1957. /* Trade time for space. This function should rarely be called
  1958. * so rather than keeping an array of pointers for the different
  1959. * messages, just run through the buffer until we find the
  1960. * correct string. */
  1961. for (s = (char *) _string_syssigmsgs ; i ; ++s) {
  1962. if (!*s) {
  1963. --i;
  1964. }
  1965. }
  1966. if (*s) { /* Make sure we have an actual message. */
  1967. goto DONE;
  1968. }
  1969. }
  1970. s = _int10tostr(buf+sizeof(buf)-1, signum) - sizeof(unknown);
  1971. memcpy(s, unknown, sizeof(unknown));
  1972. DONE:
  1973. return s;
  1974. }
  1975. #else /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
  1976. char *strsignal(int signum)
  1977. {
  1978. static char buf[_STRSIGNAL_BUFSIZE];
  1979. static const char unknown[] = {
  1980. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' '
  1981. };
  1982. return (char *) memcpy(_int10tostr(buf+sizeof(buf)-1, signum)
  1983. - sizeof(unknown),
  1984. unknown, sizeof(unknown));
  1985. }
  1986. #endif /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
  1987. #endif
  1988. /**********************************************************************/
  1989. #ifdef L_psignal
  1990. /* TODO: make this threadsafe with a reentrant version of strsignal? */
  1991. void psignal(int signum, register const char *message)
  1992. {
  1993. /* If the program is calling psignal, it's a safe bet that printf and
  1994. * friends are used as well. It is also possible that the calling
  1995. * program could buffer stderr, or reassign it. */
  1996. register const char *sep;
  1997. sep = ": ";
  1998. if (!(message && *message)) { /* Caller did not supply a prefix message */
  1999. message = (sep += 2); /* or passed an empty string. */
  2000. }
  2001. fprintf(stderr, "%s%s%s\n", message, sep, strsignal(signum));
  2002. }
  2003. #endif
  2004. /**********************************************************************/
  2005. #ifndef __LOCALE_C_ONLY
  2006. #if defined(L_strxfrm) || defined(L_strxfrm_l) || defined(L_wcsxfrm) || defined(L_wcsxfrm_l)
  2007. #ifdef L_strxfrm
  2008. #ifndef WANT_WIDE
  2009. #error WANT_WIDE should be defined for L_strxfrm
  2010. #endif
  2011. #ifdef L_wcsxfrm
  2012. #error L_wcsxfrm already defined for L_strxfrm
  2013. #endif
  2014. #endif /* L_strxfrm */
  2015. #if defined(L_strxfrm) || defined(L_strxfrm_l)
  2016. #define wcscoll strcoll
  2017. #define wcscoll_l strcoll_l
  2018. #define __wcscoll_l __strcoll_l
  2019. #define wcsxfrm strxfrm
  2020. #define wcsxfrm_l strxfrm_l
  2021. #define __wcsxfrm_l __strxfrm_l
  2022. #undef WANT_WIDE
  2023. #undef Wvoid
  2024. #undef Wchar
  2025. #undef Wuchar
  2026. #undef Wint
  2027. #define Wchar char
  2028. #endif /* defined(L_strxfrm) || defined(L_strxfrm_l) */
  2029. #if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
  2030. int wcscoll (const Wchar *s0, const Wchar *s1)
  2031. {
  2032. return __wcscoll_l(s0, s1, __UCLIBC_CURLOCALE );
  2033. }
  2034. size_t wcsxfrm(Wchar *__restrict ws1, const Wchar *__restrict ws2, size_t n)
  2035. {
  2036. return __wcsxfrm_l(ws1, ws2, n, __UCLIBC_CURLOCALE );
  2037. }
  2038. #else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  2039. #if 0
  2040. #define CUR_COLLATE (&__UCLIBC_CURLOCALE_DATA.collate)
  2041. #else
  2042. #define CUR_COLLATE (& __LOCALE_PTR->collate)
  2043. #endif
  2044. #define MAX_PENDING 8
  2045. typedef struct {
  2046. const Wchar *s;
  2047. const Wchar *eob; /* end of backward */
  2048. __uwchar_t weight;
  2049. __uwchar_t ui_weight; /* undefined or invalid */
  2050. int colitem;
  2051. int weightidx;
  2052. int rule;
  2053. size_t position;
  2054. /* should be wchar_t. if wchar < 0 do EILSEQ? */
  2055. __uwchar_t *cip;
  2056. __uwchar_t ci_pending[MAX_PENDING]; /* nul-terminated */
  2057. char *back_buf;
  2058. char *bbe; /* end of back_buf (actual last... not 1 past end) */
  2059. char *bp; /* ptr into backbuf, NULL if not in backward mode */
  2060. char ibb[128];
  2061. size_t bb_size;
  2062. int ru_pushed;
  2063. } col_state_t;
  2064. #define WEIGHT_MASK 0x3fffU
  2065. #define RULE_MASK 0xc000U
  2066. #define RULE_FORWARD (1 << 14)
  2067. #define RULE_POSITION (1 << 15)
  2068. #define UI_IDX (WEIGHT_MASK-6)
  2069. #define POSIT_IDX (WEIGHT_MASK-5)
  2070. #define RANGE_IDX (WEIGHT_MASK-4)
  2071. #define UNDEF_IDX (WEIGHT_MASK-3)
  2072. #define INVAL_IDX (WEIGHT_MASK-2)
  2073. #define DITTO_IDX (WEIGHT_MASK-1)
  2074. #undef TRACE
  2075. #if 0
  2076. #define TRACE(X) printf X
  2077. #else
  2078. #define TRACE(X) ((void)0)
  2079. #endif
  2080. static int lookup(wchar_t wc __LOCALE_PARAM )
  2081. {
  2082. unsigned int sc, n, i0, i1;
  2083. if (((__uwchar_t) wc) > 0xffffU) {
  2084. return 0;
  2085. }
  2086. sc = wc & CUR_COLLATE->ti_mask;
  2087. wc >>= CUR_COLLATE->ti_shift;
  2088. n = wc & CUR_COLLATE->ii_mask;
  2089. wc >>= CUR_COLLATE->ii_shift;
  2090. i0 = CUR_COLLATE->wcs2colidt_tbl[wc];
  2091. i0 <<= CUR_COLLATE->ii_shift;
  2092. i1 = CUR_COLLATE->wcs2colidt_tbl[CUR_COLLATE->ii_len + i0 + n];
  2093. i1 <<= CUR_COLLATE->ti_shift;
  2094. return CUR_COLLATE->wcs2colidt_tbl[CUR_COLLATE->ii_len + CUR_COLLATE->ti_len + i1 + sc];
  2095. }
  2096. static void init_col_state(col_state_t *cs, const Wchar *wcs)
  2097. {
  2098. memset(cs, 0, sizeof(col_state_t));
  2099. cs->s = wcs;
  2100. cs->bp = cs->back_buf = cs->ibb;
  2101. cs->bb_size = 128;
  2102. cs->bbe = cs->back_buf + (cs->bb_size -1);
  2103. }
  2104. static void next_weight(col_state_t *cs, int pass __LOCALE_PARAM )
  2105. {
  2106. int r, w, ru, ri, popping_backup_stack;
  2107. ssize_t n;
  2108. const uint16_t *p;
  2109. #ifdef WANT_WIDE
  2110. #define WC (*cs->s)
  2111. #define N (1)
  2112. #else /* WANT_WIDE */
  2113. wchar_t WC;
  2114. size_t n0, nx;
  2115. #define N n0
  2116. #endif /* WANT_WIDE */
  2117. do {
  2118. if (cs->ru_pushed) {
  2119. ru = cs->ru_pushed;
  2120. TRACE(("ru_pushed = %d\n", ru));
  2121. cs->ru_pushed = 0;
  2122. goto POSITION_SKIP;
  2123. }
  2124. #ifdef __UCLIBC_MJN3_ONLY__
  2125. #warning should we walk pendings backwards?
  2126. #endif
  2127. if (cs->cip) { /* possible pending weight */
  2128. if ((r = *(cs->cip++)) == 0) {
  2129. cs->cip = NULL;
  2130. continue;
  2131. }
  2132. cs->weightidx = r & WEIGHT_MASK;
  2133. assert(cs->weightidx);
  2134. /* assert(cs->weightidx != WEIGHT_MASK); */
  2135. } else { /* get the next collation item from the string */
  2136. TRACE(("clearing popping flag\n"));
  2137. popping_backup_stack = 0;
  2138. IGNORE_LOOP:
  2139. /* keep first pos as 0 for a sentinal */
  2140. if (*cs->bp) { /* pending backward chars */
  2141. POP_BACKUP:
  2142. popping_backup_stack = 1;
  2143. TRACE(("setting popping flag\n"));
  2144. n = 0;
  2145. if (*cs->bp > 0) { /* singles pending */
  2146. cs->s -= 1;
  2147. if ((*cs->bp -= 1) == 0) {
  2148. cs->bp -= 1;
  2149. }
  2150. } else { /* last was a multi */
  2151. cs->s += *cs->bp;
  2152. cs->bp -= 1;
  2153. }
  2154. } else if (!*cs->s) { /* not in backward mode and end of string */
  2155. cs->weight = 0;
  2156. return;
  2157. } else {
  2158. cs->position += 1;
  2159. }
  2160. BACK_LOOP:
  2161. #ifdef WANT_WIDE
  2162. n = 1;
  2163. cs->colitem = r = lookup(*cs->s __LOCALE_ARG );
  2164. #else /* WANT_WIDE */
  2165. n = n0 = __locale_mbrtowc_l(&WC, cs->s, __LOCALE_PTR);
  2166. if (n < 0) {
  2167. __set_errno(EILSEQ);
  2168. cs->weight = 0;
  2169. return;
  2170. }
  2171. cs->colitem = r = lookup(WC __LOCALE_ARG );
  2172. #endif /* WANT_WIDE */
  2173. TRACE((" r=%d WC=%#lx\n", r, (unsigned long)(WC)));
  2174. if (r > CUR_COLLATE->max_col_index) { /* starting char for one or more sequences */
  2175. p = CUR_COLLATE->multistart_tbl;
  2176. p += p[r-CUR_COLLATE->max_col_index -1];
  2177. do {
  2178. n = N;
  2179. r = *p++;
  2180. do {
  2181. if (!*p) { /* found it */
  2182. cs->colitem = r;
  2183. TRACE((" found multi %d\n", n));
  2184. goto FOUND;
  2185. }
  2186. #ifdef WANT_WIDE
  2187. /* the lookup check here is safe since we're assured that *p is a valid colidx */
  2188. if (!cs->s[n] || (lookup(cs->s[n] __LOCALE_ARG ) != *p)) {
  2189. do {} while (*p++);
  2190. break;
  2191. }
  2192. ++p;
  2193. ++n;
  2194. #else /* WANT_WIDE */
  2195. if (cs->s[n]) {
  2196. nx = __locale_mbrtowc_l(&WC, cs->s + n, __LOCALE_PTR);
  2197. if (nx < 0) {
  2198. __set_errno(EILSEQ);
  2199. cs->weight = 0;
  2200. return;
  2201. }
  2202. }
  2203. if (!cs->s[n] || (lookup(WC __LOCALE_ARG ) != *p)) {
  2204. do {} while (*p++);
  2205. break;
  2206. }
  2207. ++p;
  2208. n += nx; /* Only gets here if cs->s[n] != 0, so nx is set. */
  2209. #endif /* WANT_WIDE */
  2210. } while (1);
  2211. } while (1);
  2212. } else if (r == 0) { /* illegal, undefined, or part of a range */
  2213. if ((CUR_COLLATE->range_count)
  2214. #ifdef __UCLIBC_MJN3_ONLY__
  2215. #warning .. need to introduce range as a collating item?
  2216. #endif
  2217. && (((__uwchar_t)(WC - CUR_COLLATE->range_low)) <= CUR_COLLATE->range_count)
  2218. ) { /* part of a range */
  2219. /* Note: cs->colitem = 0 already. */
  2220. TRACE((" found range\n"));
  2221. ru = CUR_COLLATE->ruletable[CUR_COLLATE->range_rule_offset*CUR_COLLATE->MAX_WEIGHTS + pass];
  2222. assert((ru & WEIGHT_MASK) != DITTO_IDX);
  2223. if ((ru & WEIGHT_MASK) == WEIGHT_MASK) {
  2224. ru = (ru & RULE_MASK) | RANGE_IDX;
  2225. cs->weight = CUR_COLLATE->range_base_weight + (WC - CUR_COLLATE->range_low);
  2226. }
  2227. goto RANGE_SKIP_TO;
  2228. } else if (((__uwchar_t)(WC)) <= 0x7fffffffUL) { /* legal but undefined */
  2229. UNDEFINED:
  2230. /* Note: cs->colitem = 0 already. */
  2231. ri = CUR_COLLATE->undefined_idx;
  2232. assert(ri != 0); /* implicit undefined isn't supported */
  2233. TRACE((" found explicit UNDEFINED\n"));
  2234. #ifdef __UCLIBC_MJN3_ONLY__
  2235. #warning right now single weight locales do not support ..
  2236. #endif
  2237. if (CUR_COLLATE->num_weights == 1) {
  2238. TRACE((" single weight UNDEFINED\n"));
  2239. cs->weightidx = RANGE_IDX;
  2240. cs->weight = ri;
  2241. cs->s += n;
  2242. goto PROCESS_WEIGHT;
  2243. }
  2244. ri = CUR_COLLATE->index2ruleidx[ri - 1];
  2245. ru = CUR_COLLATE->ruletable[ri * CUR_COLLATE->MAX_WEIGHTS + pass];
  2246. assert((ru & WEIGHT_MASK) != WEIGHT_MASK); /* TODO: handle ".." */
  2247. if ((ru & WEIGHT_MASK) == DITTO_IDX) {
  2248. cs->colitem = CUR_COLLATE->undefined_idx;
  2249. }
  2250. goto RANGE_SKIP_TO;
  2251. } else { /* illegal */
  2252. TRACE((" found illegal\n"));
  2253. __set_errno(EINVAL);
  2254. /* We put all illegals in the same equiv class with maximal weight,
  2255. * and ignore them after the first pass. */
  2256. if (pass > 0) {
  2257. cs->s += n;
  2258. goto IGNORE_LOOP;
  2259. }
  2260. ru = (RULE_FORWARD | RANGE_IDX);
  2261. cs->weight = 0xffffU;
  2262. goto RANGE_SKIP_TO;
  2263. }
  2264. } else if (CUR_COLLATE->num_weights == 1) {
  2265. TRACE((" single weight\n"));
  2266. cs->weightidx = RANGE_IDX;
  2267. cs->weight = cs->colitem;
  2268. cs->s += n;
  2269. goto PROCESS_WEIGHT;
  2270. } else {
  2271. TRACE((" normal\n"));
  2272. }
  2273. /* if we get here, it is a normal char either singlely weighted, undefined, or in a range */
  2274. FOUND:
  2275. ri = CUR_COLLATE->index2ruleidx[cs->colitem - 1];
  2276. TRACE((" ri=%d ", ri));
  2277. #ifdef __UCLIBC_MJN3_ONLY__
  2278. #warning make sure this is correct
  2279. #endif
  2280. if (!ri) {
  2281. TRACE(("NOT IN THIS LOCALE\n"));
  2282. goto UNDEFINED;
  2283. }
  2284. ru = CUR_COLLATE->ruletable[ri * CUR_COLLATE->MAX_WEIGHTS + pass];
  2285. RANGE_SKIP_TO:
  2286. #ifdef __UCLIBC_MJN3_ONLY__
  2287. #warning ignoreables probably should not interrupt backwards processing, but this is wrong
  2288. #endif
  2289. /* if (!(ru & WEIGHT_MASK)) { */
  2290. /* TRACE(("IGNORE\n")); */
  2291. /* cs->s += n; */
  2292. /* continue; */
  2293. /* } */
  2294. TRACE((" rule = %#x weight = %#x popping = %d s = %p eob = %p\n",
  2295. ru & RULE_MASK, ru & WEIGHT_MASK, popping_backup_stack,
  2296. cs->s, cs->eob));
  2297. /* now we need to check if we're going backwards... */
  2298. if (!popping_backup_stack) {
  2299. if (!(ru & RULE_MASK)) { /* backward */
  2300. TRACE(("backwards\n"));
  2301. assert(cs->bp <= cs->bbe);
  2302. if (cs->bp == cs->bbe) {
  2303. if (cs->back_buf == cs->ibb) { /* was using internal buffer */
  2304. cs->bp = malloc(cs->bb_size + 128);
  2305. if (!cs->bp) {
  2306. __set_errno(ENOMEM);
  2307. #ifdef __UCLIBC_MJN3_ONLY__
  2308. #warning what to do here?
  2309. #endif
  2310. cs->weight = 0;
  2311. return;
  2312. }
  2313. memcpy(cs->bp, cs->back_buf, cs->bb_size);
  2314. } else {
  2315. cs->bp = realloc(cs->back_buf, cs->bb_size + 128);
  2316. if (!cs->bp) {
  2317. __set_errno(ENOMEM);
  2318. #ifdef __UCLIBC_MJN3_ONLY__
  2319. #warning what to do here?
  2320. #endif
  2321. cs->weight = 0;
  2322. return;
  2323. }
  2324. }
  2325. cs->bb_size += 128;
  2326. cs->bbe = cs->bp + (cs->bbe - cs->back_buf);
  2327. cs->back_buf = cs->bp;
  2328. cs->bp = cs->bbe;
  2329. }
  2330. if (n==1) { /* single char */
  2331. if (*cs->bp && (((unsigned char)(*cs->bp)) < CHAR_MAX)) {
  2332. *cs->bp += 1; /* increment last single's count */
  2333. } else { /* last was a multi, or just starting */
  2334. if (!cs->bp) {
  2335. cs->bp = cs->back_buf;
  2336. } else {
  2337. assert(cs->bp < cs->bbe);
  2338. ++cs->bp;
  2339. }
  2340. *cs->bp = 1;
  2341. }
  2342. } else { /* multichar */
  2343. assert(n>1);
  2344. assert(cs->bp < cs->bbe);
  2345. *++cs->bp = -n;
  2346. }
  2347. cs->s += n;
  2348. if (*cs->s) {
  2349. goto BACK_LOOP;
  2350. }
  2351. /* end-of-string so start popping */
  2352. cs->eob = cs->s;
  2353. TRACE(("popping\n"));
  2354. goto POP_BACKUP;
  2355. } else if (*cs->bp) { /* was going backward but this element isn't */
  2356. /* discard current and use previous backward element */
  2357. assert(!cs->cip);
  2358. cs->eob = cs->s;
  2359. TRACE(("popping\n"));
  2360. goto POP_BACKUP;
  2361. } else { /* was and still going forward */
  2362. TRACE(("forwards\n"));
  2363. if ((ru & (RULE_POSITION|WEIGHT_MASK)) > RULE_POSITION) {
  2364. assert(ru & WEIGHT_MASK);
  2365. cs->ru_pushed = ru;
  2366. cs->weight = cs->position;
  2367. #ifdef __UCLIBC_MJN3_ONLY__
  2368. #warning devel code
  2369. #endif
  2370. cs->position = 0; /* reset to reduce size for strcoll? */
  2371. cs->s += n;
  2372. cs->weightidx = RANGE_IDX;
  2373. goto PROCESS_WEIGHT;
  2374. }
  2375. }
  2376. } else { /* popping backwards stack */
  2377. TRACE(("popping (continued)\n"));
  2378. if (!*cs->bp) {
  2379. cs->s = cs->eob;
  2380. }
  2381. cs->s -= n;
  2382. }
  2383. cs->s += n;
  2384. POSITION_SKIP:
  2385. cs->weightidx = ru & WEIGHT_MASK;
  2386. cs->rule = ru & RULE_MASK;
  2387. }
  2388. #ifdef __UCLIBC_MJN3_ONLY__
  2389. #warning for pending we only want the weight... _not_ the rule
  2390. #endif
  2391. if (!cs->weightidx) { /* ignore */
  2392. continue;
  2393. }
  2394. PROCESS_WEIGHT:
  2395. assert(cs->weightidx);
  2396. if (((unsigned int)(cs->weightidx - UI_IDX)) <= (INVAL_IDX-UI_IDX)) {
  2397. if (cs->weightidx == UI_IDX) {
  2398. cs->weight = cs->ui_weight;
  2399. }
  2400. return;
  2401. }
  2402. assert(cs->weightidx != WEIGHT_MASK);
  2403. if (cs->weightidx == DITTO_IDX) { /* want the weight of the current collating item */
  2404. TRACE(("doing ditto\n"));
  2405. w = CUR_COLLATE->index2weight[cs->colitem -1];
  2406. } else if (cs->weightidx <= CUR_COLLATE->max_col_index) { /* normal */
  2407. TRACE(("doing normal\n"));
  2408. w = CUR_COLLATE->index2weight[cs->weightidx -1];
  2409. } else { /* a string */
  2410. TRACE(("doing string\n"));
  2411. assert(!(cs->weightidx & RULE_MASK));
  2412. /* note: iso14561 allows null string here */
  2413. p = CUR_COLLATE->weightstr + (cs->weightidx - (CUR_COLLATE->max_col_index + 2));
  2414. if (*p & WEIGHT_MASK) {
  2415. r = 0;
  2416. do {
  2417. assert(r < MAX_PENDING);
  2418. cs->ci_pending[r++] = *p++;
  2419. } while (*p & WEIGHT_MASK);
  2420. cs->cip = cs->ci_pending;
  2421. }
  2422. continue;
  2423. }
  2424. cs->weight = w;
  2425. return;
  2426. } while (1);
  2427. }
  2428. int __XL(wcscoll) (const Wchar *s0, const Wchar *s1 __LOCALE_PARAM )
  2429. {
  2430. col_state_t ws[2];
  2431. int pass;
  2432. if (!CUR_COLLATE->num_weights) { /* C locale */
  2433. #ifdef WANT_WIDE
  2434. return wcscmp(s0, s1);
  2435. #else /* WANT_WIDE */
  2436. return strcmp(s0, s1);
  2437. #endif /* WANT_WIDE */
  2438. }
  2439. pass = 0;
  2440. do { /* loop through the weights levels */
  2441. init_col_state(ws, s0);
  2442. init_col_state(ws+1, s1);
  2443. do { /* loop through the strings */
  2444. /* for each string, get the next weight */
  2445. next_weight(ws, pass __LOCALE_ARG );
  2446. next_weight(ws+1, pass __LOCALE_ARG );
  2447. TRACE(("w0=%lu w1=%lu\n",
  2448. (unsigned long) ws[0].weight,
  2449. (unsigned long) ws[1].weight));
  2450. if (ws[0].weight != ws[1].weight) {
  2451. return ws[0].weight - ws[1].weight;
  2452. }
  2453. } while (ws[0].weight);
  2454. } while (++pass < CUR_COLLATE->num_weights);
  2455. return 0;
  2456. }
  2457. __XL_ALIAS(wcscoll)
  2458. #ifdef WANT_WIDE
  2459. size_t __XL(wcsxfrm)(wchar_t *__restrict ws1, const wchar_t *__restrict ws2,
  2460. size_t n __LOCALE_PARAM )
  2461. {
  2462. col_state_t cs;
  2463. size_t count;
  2464. int pass;
  2465. if (!CUR_COLLATE->num_weights) { /* C locale */
  2466. return __wcslcpy(ws1, ws2, n);
  2467. }
  2468. #ifdef __UCLIBC_MJN3_ONLY__
  2469. #warning handle empty string as a special case
  2470. #endif
  2471. count = pass = 0;
  2472. do { /* loop through the weights levels */
  2473. init_col_state(&cs, ws2);
  2474. do { /* loop through the string */
  2475. next_weight(&cs, pass __LOCALE_ARG );
  2476. TRACE(("weight=%lu (%#lx)\n", (unsigned long) cs.weight, (unsigned long) cs.weight));
  2477. if (count < n) {
  2478. ws1[count] = cs.weight +1;
  2479. }
  2480. ++count;
  2481. TRACE(("--------------------------------------------\n"));
  2482. } while (cs.weight);
  2483. if (count <= n) { /* overwrite the trailing 0 end-of-pass marker */
  2484. ws1[count-1] = 1;
  2485. }
  2486. TRACE(("-------------------- pass %d --------------------\n", pass));
  2487. } while (++pass < CUR_COLLATE->num_weights);
  2488. if (count <= n) { /* oops... change it back */
  2489. ws1[count-1] = 0;
  2490. }
  2491. return count-1;
  2492. }
  2493. __XL_ALIAS(wcsxfrm)
  2494. #else /* WANT_WIDE */
  2495. static const unsigned long bound[] = {
  2496. 1UL << 7,
  2497. 1UL << 11,
  2498. 1UL << 16,
  2499. 1UL << 21,
  2500. 1UL << 26,
  2501. };
  2502. static unsigned char first[] = {
  2503. 0x0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
  2504. };
  2505. /* Use an extension of UTF-8 to store a 32 bit val in max 6 bytes. */
  2506. static size_t store(unsigned char *s, size_t count, size_t n, __uwchar_t weight)
  2507. {
  2508. int i, r;
  2509. i = 0;
  2510. do {
  2511. if (weight < bound[i]) {
  2512. break;
  2513. }
  2514. } while (++i < sizeof(bound)/sizeof(bound[0]));
  2515. r = i+1;
  2516. if (i + count < n) {
  2517. s += count;
  2518. s[0] = first[i];
  2519. while (i) {
  2520. s[i] = 0x80 | (weight & 0x3f);
  2521. weight >>= 6;
  2522. --i;
  2523. }
  2524. s[0] |= weight;
  2525. }
  2526. return r;
  2527. }
  2528. size_t __XL(strxfrm)(char *__restrict ws1, const char *__restrict ws2, size_t n
  2529. __LOCALE_PARAM )
  2530. {
  2531. col_state_t cs;
  2532. size_t count, inc;
  2533. int pass;
  2534. if (!CUR_COLLATE->num_weights) { /* C locale */
  2535. return strlcpy(ws1, ws2, n);
  2536. }
  2537. #ifdef __UCLIBC_MJN3_ONLY__
  2538. #warning handle empty string as a special case
  2539. #endif
  2540. inc = count = pass = 0;
  2541. do { /* loop through the weights levels */
  2542. init_col_state(&cs, ws2);
  2543. do { /* loop through the string */
  2544. next_weight(&cs, pass __LOCALE_ARG );
  2545. TRACE(("weight=%lu (%#lx)\n", (unsigned long) cs.weight, (unsigned long) cs.weight));
  2546. inc = store((unsigned char *)ws1, count, n, cs.weight + 1);
  2547. count += inc;
  2548. TRACE(("--------------------------------------------\n"));
  2549. } while (cs.weight);
  2550. /* overwrite the trailing 0 end-of-pass marker */
  2551. assert(inc == 1);
  2552. if (count <= n) {
  2553. ws1[count-1] = 1;
  2554. }
  2555. TRACE(("-------------------- pass %d --------------------\n", pass));
  2556. } while (++pass < CUR_COLLATE->num_weights);
  2557. if (count <= n) { /* oops... change it back */
  2558. ws1[count-1] = 0;
  2559. }
  2560. return count-1;
  2561. }
  2562. __XL_ALIAS(strxfrm)
  2563. #endif /* WANT_WIDE */
  2564. #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
  2565. #endif /* defined(L_strxfrm) || defined(L_strxfrm_l) || defined(L_wcsxfrm) || defined(L_wcsxfrm_l) */
  2566. #endif /* __LOCALE_C_ONLY */
  2567. /**********************************************************************/