URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/trunk/linux/uClibc/libc/string
- from Rev 1325 to Rev 1765
- ↔ Reverse comparison
Rev 1325 → Rev 1765
/arm/memcmp.S
0,0 → 1,57
/* |
* Copyright (c) 2002 ARM Ltd |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. The name of the company may not be used to endorse or promote |
* products derived from this software without specific prior written |
* permission. |
* |
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* Adapted for uClibc from NetBSD memcmp.S, version 1.2 2003/04/05 |
* by Erik Andersen <andersen@codepoet.org> |
*/ |
|
|
.text |
.global memcmp; |
.type memcmp,%function |
.align 4; \ |
|
memcmp: |
/* if ((len - 1) < 0) return 0 */ |
subs r2, r2, #1 |
movmi r0, #0 |
movmi pc, lr |
|
/* ip == last src address to compare */ |
add ip, r0, r2 |
1: |
ldrb r2, [r0], #1 |
ldrb r3, [r1], #1 |
cmp ip, r0 |
cmpcs r2, r3 |
beq 1b |
sub r0, r2, r3 |
mov pc, lr |
|
.weak bcmp; |
bcmp = memcmp |
|
/arm/bzero.S
0,0 → 1,48
/*- |
* Copyright (c) 1997 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Neil A. Carson and Mark Brinicombe |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the NetBSD |
* Foundation, Inc. and its contributors. |
* 4. Neither the name of The NetBSD Foundation nor the names of its |
* contributors may be used to endorse or promote products derived |
* from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
* |
* Adapted for uClibc from NetBSD bzero.S,v 1.2 1997/10/09 |
* by Erik Andersen <andersen@codepoet.org> |
*/ |
|
.text |
.global bzero; |
.type bzero,%function |
.align 4; \ |
|
bzero: |
mov r2, r1 |
mov r1, #0 |
b memset (PLT) |
/arm/memmove.S
0,0 → 1,48
/*- |
* Copyright (c) 1997 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Neil A. Carson and Mark Brinicombe |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the NetBSD |
* Foundation, Inc. and its contributors. |
* 4. Neither the name of The NetBSD Foundation nor the names of its |
* contributors may be used to endorse or promote products derived |
* from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
* |
* Adapted for uClibc from NetBSD memmove.S,v 1.3 2003/04/05 |
* by Erik Andersen <andersen@codepoet.org> |
*/ |
|
.text |
.global memmove; |
.type memmove,%function |
.align 4; \ |
|
memmove: |
stmfd sp!, {r0, lr} |
bl _memcpy (PLT) |
ldmfd sp!, {r0, pc} |
/arm/strncmp.S
0,0 → 1,53
/* |
* Copyright (c) 2002 ARM Ltd |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. The name of the company may not be used to endorse or promote |
* products derived from this software without specific prior written |
* permission. |
* |
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* Adapted for uClibc from NetBSD strncmp.S, version 1.2 2003/04/05 |
* by Erik Andersen <andersen@codepoet.org> |
*/ |
|
.text |
.global strncmp; |
.type strncmp,%function |
.align 4; \ |
|
strncmp: |
/* if ((len - 1) < 0) return 0 */ |
subs r2, r2, #1 |
movmi r0, #0 |
movmi pc, lr |
|
/* ip == last src address to compare */ |
add ip, r0, r2 |
1: |
ldrb r2, [r0], #1 |
ldrb r3, [r1], #1 |
cmp ip, r0 |
cmpcs r2, #1 |
cmpcs r2, r3 |
beq 1b |
sub r0, r2, r3 |
mov pc, lr |
/arm/strlen.S
0,0 → 1,71
/* Copyright (C) 1998 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Code contributed by Matthew Wilcox <willy@odie.barnet.ac.uk> |
|
The GNU C Library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; either |
version 2.1 of the License, or (at your option) any later version. |
|
The GNU C Library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with the GNU C Library; if not, write to the Free |
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
02111-1307 USA. */ |
|
#include <endian.h> |
#include <sys/syscall.h> |
|
/* size_t strlen(const char *S) |
* entry: r0 -> string |
* exit: r0 = len |
*/ |
|
.text |
.global strlen; |
.type strlen,%function |
.align 4; \ |
|
strlen: |
bic r1, r0, $3 @ addr of word containing first byte |
ldr r2, [r1], $4 @ get the first word |
ands r3, r0, $3 @ how many bytes are duff? |
rsb r0, r3, $0 @ get - that number into counter. |
beq Laligned @ skip into main check routine if no |
@ more |
#if __BYTE_ORDER == __BIG_ENDIAN |
orr r2, r2, $0xff000000 @ set this byte to non-zero |
subs r3, r3, $1 @ any more to do? |
orrgt r2, r2, $0x00ff0000 @ if so, set this byte |
subs r3, r3, $1 @ more? |
orrgt r2, r2, $0x0000ff00 @ then set. |
#else |
orr r2, r2, $0x000000ff @ set this byte to non-zero |
subs r3, r3, $1 @ any more to do? |
orrgt r2, r2, $0x0000ff00 @ if so, set this byte |
subs r3, r3, $1 @ more? |
orrgt r2, r2, $0x00ff0000 @ then set. |
#endif |
Laligned: @ here, we have a word in r2. Does it |
tst r2, $0x000000ff @ contain any zeroes? |
tstne r2, $0x0000ff00 @ |
tstne r2, $0x00ff0000 @ |
tstne r2, $0xff000000 @ |
addne r0, r0, $4 @ if not, the string is 4 bytes longer |
ldrne r2, [r1], $4 @ and we continue to the next word |
bne Laligned @ |
Llastword: @ drop through to here once we find a |
tst r2, $0x000000ff @ word that has a zero byte in it |
addne r0, r0, $1 @ |
tstne r2, $0x0000ff00 @ and add up to 3 bytes on to it |
addne r0, r0, $1 @ |
tstne r2, $0x00ff0000 @ (if first three all non-zero, 4th |
addne r0, r0, $1 @ must be zero) |
mov pc,lr |
|
.size strlen,.-strlen; |
|
/arm/strcmp.S
0,0 → 1,49
/* |
* Copyright (c) 2002 ARM Ltd |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. The name of the company may not be used to endorse or promote |
* products derived from this software without specific prior written |
* permission. |
* |
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* Adapted for uClibc from NetBSD strcmp.S, version 1.3 2003/04/05 |
* by Erik Andersen <andersen@codepoet.org> |
*/ |
|
.text |
.global strcmp; |
.type strcmp,%function |
.align 4; \ |
|
strcmp: |
1: |
ldrb r2, [r0], #1 |
ldrb r3, [r1], #1 |
cmp r2, #1 |
cmpcs r2, r3 |
beq 1b |
sub r0, r2, r3 |
mov pc, lr |
|
.weak strcoll; |
strcoll = strcmp |
|
/arm/_memcpy.S
0,0 → 1,583
/*- |
* Copyright (c) 1997 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Neil A. Carson and Mark Brinicombe |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the NetBSD |
* Foundation, Inc. and its contributors. |
* 4. Neither the name of The NetBSD Foundation nor the names of its |
* contributors may be used to endorse or promote products derived |
* from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
* |
* Adapted for uClibc from NetBSD _memcpy.S,v 1.6 2003/10/09 |
* by Erik Andersen <andersen@codepoet.org> |
*/ |
|
|
#include <endian.h> |
|
/* |
* This is one fun bit of code ... |
* Some easy listening music is suggested while trying to understand this |
* code e.g. Iron Maiden |
* |
* For anyone attempting to understand it : |
* |
* The core code is implemented here with simple stubs for memcpy() |
* memmove() and bcopy(). |
* |
* All local labels are prefixed with Lmemcpy_ |
* Following the prefix a label starting f is used in the forward copy code |
* while a label using b is used in the backwards copy code |
* The source and destination addresses determine whether a forward or |
* backward copy is performed. |
* Separate bits of code are used to deal with the following situations |
* for both the forward and backwards copy. |
* unaligned source address |
* unaligned destination address |
* Separate copy routines are used to produce an optimised result for each |
* of these cases. |
* The copy code will use LDM/STM instructions to copy up to 32 bytes at |
* a time where possible. |
* |
* Note: r12 (aka ip) can be trashed during the function along with |
* r0-r3 although r0-r2 have defined uses i.e. src, dest, len through out. |
* Additional registers are preserved prior to use i.e. r4, r5 & lr |
* |
* Apologies for the state of the comments ;-) |
*/ |
|
.text |
.global _memcpy; |
.type _memcpy,%function |
.align 4; \ |
|
_memcpy: |
/* Determine copy direction */ |
cmp r1, r0 |
bcc .Lmemcpy_backwards |
|
moveq r0, #0 /* Quick abort for len=0 */ |
moveq pc, lr |
|
stmdb sp!, {r0, lr} /* memcpy() returns dest addr */ |
subs r2, r2, #4 |
blt .Lmemcpy_fl4 /* less than 4 bytes */ |
ands r12, r0, #3 |
bne .Lmemcpy_fdestul /* oh unaligned destination addr */ |
ands r12, r1, #3 |
bne .Lmemcpy_fsrcul /* oh unaligned source addr */ |
|
.Lmemcpy_ft8: |
/* We have aligned source and destination */ |
subs r2, r2, #8 |
blt .Lmemcpy_fl12 /* less than 12 bytes (4 from above) */ |
subs r2, r2, #0x14 |
blt .Lmemcpy_fl32 /* less than 32 bytes (12 from above) */ |
stmdb sp!, {r4} /* borrow r4 */ |
|
/* blat 32 bytes at a time */ |
/* XXX for really big copies perhaps we should use more registers */ |
.Lmemcpy_floop32: |
ldmia r1!, {r3, r4, r12, lr} |
stmia r0!, {r3, r4, r12, lr} |
ldmia r1!, {r3, r4, r12, lr} |
stmia r0!, {r3, r4, r12, lr} |
subs r2, r2, #0x20 |
bge .Lmemcpy_floop32 |
|
cmn r2, #0x10 |
ldmgeia r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ |
stmgeia r0!, {r3, r4, r12, lr} |
subge r2, r2, #0x10 |
ldmia sp!, {r4} /* return r4 */ |
|
.Lmemcpy_fl32: |
adds r2, r2, #0x14 |
|
/* blat 12 bytes at a time */ |
.Lmemcpy_floop12: |
ldmgeia r1!, {r3, r12, lr} |
stmgeia r0!, {r3, r12, lr} |
subges r2, r2, #0x0c |
bge .Lmemcpy_floop12 |
|
.Lmemcpy_fl12: |
adds r2, r2, #8 |
blt .Lmemcpy_fl4 |
|
subs r2, r2, #4 |
ldrlt r3, [r1], #4 |
strlt r3, [r0], #4 |
ldmgeia r1!, {r3, r12} |
stmgeia r0!, {r3, r12} |
subge r2, r2, #4 |
|
.Lmemcpy_fl4: |
/* less than 4 bytes to go */ |
adds r2, r2, #4 |
ldmeqia sp!, {r0, pc} /* done */ |
|
/* copy the crud byte at a time */ |
cmp r2, #2 |
ldrb r3, [r1], #1 |
strb r3, [r0], #1 |
ldrgeb r3, [r1], #1 |
strgeb r3, [r0], #1 |
ldrgtb r3, [r1], #1 |
strgtb r3, [r0], #1 |
ldmia sp!, {r0, pc} |
|
/* erg - unaligned destination */ |
.Lmemcpy_fdestul: |
rsb r12, r12, #4 |
cmp r12, #2 |
|
/* align destination with byte copies */ |
ldrb r3, [r1], #1 |
strb r3, [r0], #1 |
ldrgeb r3, [r1], #1 |
strgeb r3, [r0], #1 |
ldrgtb r3, [r1], #1 |
strgtb r3, [r0], #1 |
subs r2, r2, r12 |
blt .Lmemcpy_fl4 /* less the 4 bytes */ |
|
ands r12, r1, #3 |
beq .Lmemcpy_ft8 /* we have an aligned source */ |
|
/* erg - unaligned source */ |
/* This is where it gets nasty ... */ |
.Lmemcpy_fsrcul: |
bic r1, r1, #3 |
ldr lr, [r1], #4 |
cmp r12, #2 |
bgt .Lmemcpy_fsrcul3 |
beq .Lmemcpy_fsrcul2 |
cmp r2, #0x0c |
blt .Lmemcpy_fsrcul1loop4 |
sub r2, r2, #0x0c |
stmdb sp!, {r4, r5} |
|
.Lmemcpy_fsrcul1loop16: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov r3, lr, lsl #8 |
ldmia r1!, {r4, r5, r12, lr} |
orr r3, r3, r4, lsr #24 |
mov r4, r4, lsl #8 |
orr r4, r4, r5, lsr #24 |
mov r5, r5, lsl #8 |
orr r5, r5, r12, lsr #24 |
mov r12, r12, lsl #8 |
orr r12, r12, lr, lsr #24 |
#else |
mov r3, lr, lsr #8 |
ldmia r1!, {r4, r5, r12, lr} |
orr r3, r3, r4, lsl #24 |
mov r4, r4, lsr #8 |
orr r4, r4, r5, lsl #24 |
mov r5, r5, lsr #8 |
orr r5, r5, r12, lsl #24 |
mov r12, r12, lsr #8 |
orr r12, r12, lr, lsl #24 |
#endif |
stmia r0!, {r3-r5, r12} |
subs r2, r2, #0x10 |
bge .Lmemcpy_fsrcul1loop16 |
ldmia sp!, {r4, r5} |
adds r2, r2, #0x0c |
blt .Lmemcpy_fsrcul1l4 |
|
.Lmemcpy_fsrcul1loop4: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov r12, lr, lsl #8 |
ldr lr, [r1], #4 |
orr r12, r12, lr, lsr #24 |
#else |
mov r12, lr, lsr #8 |
ldr lr, [r1], #4 |
orr r12, r12, lr, lsl #24 |
#endif |
str r12, [r0], #4 |
subs r2, r2, #4 |
bge .Lmemcpy_fsrcul1loop4 |
|
.Lmemcpy_fsrcul1l4: |
sub r1, r1, #3 |
b .Lmemcpy_fl4 |
|
.Lmemcpy_fsrcul2: |
cmp r2, #0x0c |
blt .Lmemcpy_fsrcul2loop4 |
sub r2, r2, #0x0c |
stmdb sp!, {r4, r5} |
|
.Lmemcpy_fsrcul2loop16: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov r3, lr, lsl #16 |
ldmia r1!, {r4, r5, r12, lr} |
orr r3, r3, r4, lsr #16 |
mov r4, r4, lsl #16 |
orr r4, r4, r5, lsr #16 |
mov r5, r5, lsl #16 |
orr r5, r5, r12, lsr #16 |
mov r12, r12, lsl #16 |
orr r12, r12, lr, lsr #16 |
#else |
mov r3, lr, lsr #16 |
ldmia r1!, {r4, r5, r12, lr} |
orr r3, r3, r4, lsl #16 |
mov r4, r4, lsr #16 |
orr r4, r4, r5, lsl #16 |
mov r5, r5, lsr #16 |
orr r5, r5, r12, lsl #16 |
mov r12, r12, lsr #16 |
orr r12, r12, lr, lsl #16 |
#endif |
stmia r0!, {r3-r5, r12} |
subs r2, r2, #0x10 |
bge .Lmemcpy_fsrcul2loop16 |
ldmia sp!, {r4, r5} |
adds r2, r2, #0x0c |
blt .Lmemcpy_fsrcul2l4 |
|
.Lmemcpy_fsrcul2loop4: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov r12, lr, lsl #16 |
ldr lr, [r1], #4 |
orr r12, r12, lr, lsr #16 |
#else |
mov r12, lr, lsr #16 |
ldr lr, [r1], #4 |
orr r12, r12, lr, lsl #16 |
#endif |
str r12, [r0], #4 |
subs r2, r2, #4 |
bge .Lmemcpy_fsrcul2loop4 |
|
.Lmemcpy_fsrcul2l4: |
sub r1, r1, #2 |
b .Lmemcpy_fl4 |
|
.Lmemcpy_fsrcul3: |
cmp r2, #0x0c |
blt .Lmemcpy_fsrcul3loop4 |
sub r2, r2, #0x0c |
stmdb sp!, {r4, r5} |
|
.Lmemcpy_fsrcul3loop16: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov r3, lr, lsl #24 |
ldmia r1!, {r4, r5, r12, lr} |
orr r3, r3, r4, lsr #8 |
mov r4, r4, lsl #24 |
orr r4, r4, r5, lsr #8 |
mov r5, r5, lsl #24 |
orr r5, r5, r12, lsr #8 |
mov r12, r12, lsl #24 |
orr r12, r12, lr, lsr #8 |
#else |
mov r3, lr, lsr #24 |
ldmia r1!, {r4, r5, r12, lr} |
orr r3, r3, r4, lsl #8 |
mov r4, r4, lsr #24 |
orr r4, r4, r5, lsl #8 |
mov r5, r5, lsr #24 |
orr r5, r5, r12, lsl #8 |
mov r12, r12, lsr #24 |
orr r12, r12, lr, lsl #8 |
#endif |
stmia r0!, {r3-r5, r12} |
subs r2, r2, #0x10 |
bge .Lmemcpy_fsrcul3loop16 |
ldmia sp!, {r4, r5} |
adds r2, r2, #0x0c |
blt .Lmemcpy_fsrcul3l4 |
|
.Lmemcpy_fsrcul3loop4: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov r12, lr, lsl #24 |
ldr lr, [r1], #4 |
orr r12, r12, lr, lsr #8 |
#else |
mov r12, lr, lsr #24 |
ldr lr, [r1], #4 |
orr r12, r12, lr, lsl #8 |
#endif |
str r12, [r0], #4 |
subs r2, r2, #4 |
bge .Lmemcpy_fsrcul3loop4 |
|
.Lmemcpy_fsrcul3l4: |
sub r1, r1, #1 |
b .Lmemcpy_fl4 |
|
.Lmemcpy_backwards: |
add r1, r1, r2 |
add r0, r0, r2 |
subs r2, r2, #4 |
blt .Lmemcpy_bl4 /* less than 4 bytes */ |
ands r12, r0, #3 |
bne .Lmemcpy_bdestul /* oh unaligned destination addr */ |
ands r12, r1, #3 |
bne .Lmemcpy_bsrcul /* oh unaligned source addr */ |
|
.Lmemcpy_bt8: |
/* We have aligned source and destination */ |
subs r2, r2, #8 |
blt .Lmemcpy_bl12 /* less than 12 bytes (4 from above) */ |
stmdb sp!, {r4, lr} |
subs r2, r2, #0x14 /* less than 32 bytes (12 from above) */ |
blt .Lmemcpy_bl32 |
|
/* blat 32 bytes at a time */ |
/* XXX for really big copies perhaps we should use more registers */ |
.Lmemcpy_bloop32: |
ldmdb r1!, {r3, r4, r12, lr} |
stmdb r0!, {r3, r4, r12, lr} |
ldmdb r1!, {r3, r4, r12, lr} |
stmdb r0!, {r3, r4, r12, lr} |
subs r2, r2, #0x20 |
bge .Lmemcpy_bloop32 |
|
.Lmemcpy_bl32: |
cmn r2, #0x10 |
ldmgedb r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ |
stmgedb r0!, {r3, r4, r12, lr} |
subge r2, r2, #0x10 |
adds r2, r2, #0x14 |
ldmgedb r1!, {r3, r12, lr} /* blat a remaining 12 bytes */ |
stmgedb r0!, {r3, r12, lr} |
subge r2, r2, #0x0c |
ldmia sp!, {r4, lr} |
|
.Lmemcpy_bl12: |
adds r2, r2, #8 |
blt .Lmemcpy_bl4 |
subs r2, r2, #4 |
ldrlt r3, [r1, #-4]! |
strlt r3, [r0, #-4]! |
ldmgedb r1!, {r3, r12} |
stmgedb r0!, {r3, r12} |
subge r2, r2, #4 |
|
.Lmemcpy_bl4: |
/* less than 4 bytes to go */ |
adds r2, r2, #4 |
moveq pc, lr /* done */ |
|
/* copy the crud byte at a time */ |
cmp r2, #2 |
ldrb r3, [r1, #-1]! |
strb r3, [r0, #-1]! |
ldrgeb r3, [r1, #-1]! |
strgeb r3, [r0, #-1]! |
ldrgtb r3, [r1, #-1]! |
strgtb r3, [r0, #-1]! |
mov pc, lr |
|
/* erg - unaligned destination */ |
.Lmemcpy_bdestul: |
cmp r12, #2 |
|
/* align destination with byte copies */ |
ldrb r3, [r1, #-1]! |
strb r3, [r0, #-1]! |
ldrgeb r3, [r1, #-1]! |
strgeb r3, [r0, #-1]! |
ldrgtb r3, [r1, #-1]! |
strgtb r3, [r0, #-1]! |
subs r2, r2, r12 |
blt .Lmemcpy_bl4 /* less than 4 bytes to go */ |
ands r12, r1, #3 |
beq .Lmemcpy_bt8 /* we have an aligned source */ |
|
/* erg - unaligned source */ |
/* This is where it gets nasty ... */ |
.Lmemcpy_bsrcul: |
bic r1, r1, #3 |
ldr r3, [r1, #0] |
cmp r12, #2 |
blt .Lmemcpy_bsrcul1 |
beq .Lmemcpy_bsrcul2 |
cmp r2, #0x0c |
blt .Lmemcpy_bsrcul3loop4 |
sub r2, r2, #0x0c |
stmdb sp!, {r4, r5, lr} |
|
.Lmemcpy_bsrcul3loop16: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov lr, r3, lsr #8 |
ldmdb r1!, {r3-r5, r12} |
orr lr, lr, r12, lsl #24 |
mov r12, r12, lsr #8 |
orr r12, r12, r5, lsl #24 |
mov r5, r5, lsr #8 |
orr r5, r5, r4, lsl #24 |
mov r4, r4, lsr #8 |
orr r4, r4, r3, lsl #24 |
#else |
mov lr, r3, lsl #8 |
ldmdb r1!, {r3-r5, r12} |
orr lr, lr, r12, lsr #24 |
mov r12, r12, lsl #8 |
orr r12, r12, r5, lsr #24 |
mov r5, r5, lsl #8 |
orr r5, r5, r4, lsr #24 |
mov r4, r4, lsl #8 |
orr r4, r4, r3, lsr #24 |
#endif |
stmdb r0!, {r4, r5, r12, lr} |
subs r2, r2, #0x10 |
bge .Lmemcpy_bsrcul3loop16 |
ldmia sp!, {r4, r5, lr} |
adds r2, r2, #0x0c |
blt .Lmemcpy_bsrcul3l4 |
|
.Lmemcpy_bsrcul3loop4: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov r12, r3, lsr #8 |
ldr r3, [r1, #-4]! |
orr r12, r12, r3, lsl #24 |
#else |
mov r12, r3, lsl #8 |
ldr r3, [r1, #-4]! |
orr r12, r12, r3, lsr #24 |
#endif |
str r12, [r0, #-4]! |
subs r2, r2, #4 |
bge .Lmemcpy_bsrcul3loop4 |
|
.Lmemcpy_bsrcul3l4: |
add r1, r1, #3 |
b .Lmemcpy_bl4 |
|
.Lmemcpy_bsrcul2: |
cmp r2, #0x0c |
blt .Lmemcpy_bsrcul2loop4 |
sub r2, r2, #0x0c |
stmdb sp!, {r4, r5, lr} |
|
.Lmemcpy_bsrcul2loop16: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov lr, r3, lsr #16 |
ldmdb r1!, {r3-r5, r12} |
orr lr, lr, r12, lsl #16 |
mov r12, r12, lsr #16 |
orr r12, r12, r5, lsl #16 |
mov r5, r5, lsr #16 |
orr r5, r5, r4, lsl #16 |
mov r4, r4, lsr #16 |
orr r4, r4, r3, lsl #16 |
#else |
mov lr, r3, lsl #16 |
ldmdb r1!, {r3-r5, r12} |
orr lr, lr, r12, lsr #16 |
mov r12, r12, lsl #16 |
orr r12, r12, r5, lsr #16 |
mov r5, r5, lsl #16 |
orr r5, r5, r4, lsr #16 |
mov r4, r4, lsl #16 |
orr r4, r4, r3, lsr #16 |
#endif |
stmdb r0!, {r4, r5, r12, lr} |
subs r2, r2, #0x10 |
bge .Lmemcpy_bsrcul2loop16 |
ldmia sp!, {r4, r5, lr} |
adds r2, r2, #0x0c |
blt .Lmemcpy_bsrcul2l4 |
|
.Lmemcpy_bsrcul2loop4: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov r12, r3, lsr #16 |
ldr r3, [r1, #-4]! |
orr r12, r12, r3, lsl #16 |
#else |
mov r12, r3, lsl #16 |
ldr r3, [r1, #-4]! |
orr r12, r12, r3, lsr #16 |
#endif |
str r12, [r0, #-4]! |
subs r2, r2, #4 |
bge .Lmemcpy_bsrcul2loop4 |
|
.Lmemcpy_bsrcul2l4: |
add r1, r1, #2 |
b .Lmemcpy_bl4 |
|
.Lmemcpy_bsrcul1: |
cmp r2, #0x0c |
blt .Lmemcpy_bsrcul1loop4 |
sub r2, r2, #0x0c |
stmdb sp!, {r4, r5, lr} |
|
.Lmemcpy_bsrcul1loop32: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov lr, r3, lsr #24 |
ldmdb r1!, {r3-r5, r12} |
orr lr, lr, r12, lsl #8 |
mov r12, r12, lsr #24 |
orr r12, r12, r5, lsl #8 |
mov r5, r5, lsr #24 |
orr r5, r5, r4, lsl #8 |
mov r4, r4, lsr #24 |
orr r4, r4, r3, lsl #8 |
#else |
mov lr, r3, lsl #24 |
ldmdb r1!, {r3-r5, r12} |
orr lr, lr, r12, lsr #8 |
mov r12, r12, lsl #24 |
orr r12, r12, r5, lsr #8 |
mov r5, r5, lsl #24 |
orr r5, r5, r4, lsr #8 |
mov r4, r4, lsl #24 |
orr r4, r4, r3, lsr #8 |
#endif |
stmdb r0!, {r4, r5, r12, lr} |
subs r2, r2, #0x10 |
bge .Lmemcpy_bsrcul1loop32 |
ldmia sp!, {r4, r5, lr} |
adds r2, r2, #0x0c |
blt .Lmemcpy_bsrcul1l4 |
|
.Lmemcpy_bsrcul1loop4: |
#if __BYTE_ORDER == __BIG_ENDIAN |
mov r12, r3, lsr #24 |
ldr r3, [r1, #-4]! |
orr r12, r12, r3, lsl #8 |
#else |
mov r12, r3, lsl #24 |
ldr r3, [r1, #-4]! |
orr r12, r12, r3, lsr #8 |
#endif |
str r12, [r0, #-4]! |
subs r2, r2, #4 |
bge .Lmemcpy_bsrcul1loop4 |
|
.Lmemcpy_bsrcul1l4: |
add r1, r1, #1 |
b .Lmemcpy_bl4 |
/arm/memcpy.S
0,0 → 1,48
/*- |
* Copyright (c) 1997 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Neil A. Carson and Mark Brinicombe |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the NetBSD |
* Foundation, Inc. and its contributors. |
* 4. Neither the name of The NetBSD Foundation nor the names of its |
* contributors may be used to endorse or promote products derived |
* from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
* |
* Adapted for uClibc from NetBSD memcpy.S,v 1.3 2003/04/05 |
* by Erik Andersen <andersen@codepoet.org> |
*/ |
|
.text |
.global memcpy; |
.type memcpy,%function |
.align 4; \ |
|
memcpy: |
stmfd sp!, {r0, lr} |
bl _memcpy (PLT) |
ldmfd sp!, {r0, pc} |
/arm/memset.S
0,0 → 1,72
/* Copyright (C) 1998 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Philip Blundell <philb@gnu.org> |
|
The GNU C Library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; either |
version 2.1 of the License, or (at your option) any later version. |
|
The GNU C Library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with the GNU C Library; if not, write to the Free |
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
02111-1307 USA. */ |
|
#include <sys/syscall.h> |
|
.text |
.global memset; |
.type memset,%function |
.align 4; \ |
|
memset: |
mov a4, a1 |
cmp a3, $8 @ at least 8 bytes to do? |
blt 2f |
orr a2, a2, a2, lsl $8 |
orr a2, a2, a2, lsl $16 |
1: |
tst a4, $3 @ aligned yet? |
strneb a2, [a4], $1 |
subne a3, a3, $1 |
bne 1b |
mov ip, a2 |
1: |
cmp a3, $8 @ 8 bytes still to do? |
blt 2f |
stmia a4!, {a2, ip} |
sub a3, a3, $8 |
cmp a3, $8 @ 8 bytes still to do? |
blt 2f |
stmia a4!, {a2, ip} |
sub a3, a3, $8 |
cmp a3, $8 @ 8 bytes still to do? |
blt 2f |
stmia a4!, {a2, ip} |
sub a3, a3, $8 |
cmp a3, $8 @ 8 bytes still to do? |
stmgeia a4!, {a2, ip} |
subge a3, a3, $8 |
bge 1b |
2: |
movs a3, a3 @ anything left? |
moveq pc, lr @ nope |
rsb a3, a3, $7 |
add pc, pc, a3, lsl $2 |
mov r0, r0 |
strb a2, [a4], $1 |
strb a2, [a4], $1 |
strb a2, [a4], $1 |
strb a2, [a4], $1 |
strb a2, [a4], $1 |
strb a2, [a4], $1 |
strb a2, [a4], $1 |
mov pc, lr |
|
.size memset,.-memset; |
|
/arm/Makefile
0,0 → 1,39
# Makefile for uClibc |
# |
# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org> |
# |
# This program is free software; you can redistribute it and/or modify it under |
# the terms of the GNU Library General Public License as published by the Free |
# Software Foundation; either version 2 of the License, or (at your option) any |
# later version. |
# |
# This program is distributed in the hope that it will be useful, but WITHOUT |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more |
# details. |
# |
# You should have received a copy of the GNU Library General Public License |
# along with this program; if not, write to the Free Software Foundation, Inc., |
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
TOPDIR=../../../ |
include $(TOPDIR)Rules.mak |
|
SSRC= _memcpy.S bcopy.S bzero.S memcmp.S memcpy.S memmove.S memset.S \ |
strcmp.S strlen.S strncmp.S |
SOBJS=$(patsubst %.S,%.o, $(SSRC)) |
|
all: $(SOBJS) $(LIBC) |
|
$(LIBC): ar-target |
|
ar-target: $(SOBJS) |
$(AR) $(ARFLAGS) $(LIBC) $(SOBJS) |
|
$(SOBJS): %.o : %.S |
$(CC) $(CFLAGS) -c $< -o $@ |
$(STRIPTOOL) -x -R .note -R .comment $*.o |
|
clean: |
$(RM) *.[oa] *~ core |
|
/arm/bcopy.S
0,0 → 1,52
/*- |
* Copyright (c) 1997 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Neil A. Carson and Mark Brinicombe |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the NetBSD |
* Foundation, Inc. and its contributors. |
* 4. Neither the name of The NetBSD Foundation nor the names of its |
* contributors may be used to endorse or promote products derived |
* from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
* |
* Adapted for uClibc from NetBSD bcopy.S,v 1.2 1997/10/09 |
* by Erik Andersen <andersen@codepoet.org> |
*/ |
|
/* bcopy = memcpy/memmove with arguments reversed. */ |
|
.text |
.global bcopy; |
.type bcopy,%function |
.align 4; \ |
|
bcopy: |
/* switch the source and destination registers */ |
eor r0, r1, r0 |
eor r1, r0, r1 |
eor r0, r1, r0 |
b _memcpy (PLT) |
/sh64/strcpy.S
0,0 → 1,98
/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */ |
/* Modified by SuperH, Inc. September 2003 */ |
! Entry: arg0: destination |
! arg1: source |
! Exit: result: destination |
! |
! SH5 code Copyright 2002 SuperH Ltd. |
|
#ifdef __LITTLE_ENDIAN__ |
#define SHHI shlld |
#define SHLO shlrd |
#else |
#define SHHI shlrd |
#define SHLO shlld |
#endif |
|
.section .text..SHmedia32,"ax" |
.globl strcpy |
.type strcpy, @function |
|
.align 5 |
strcpy: |
|
pta/l shortstring,tr1 |
ldlo.q r3,0,r4 |
ptabs r18,tr4 |
shlli r3,3,r7 |
addi r2, 8, r0 |
mcmpeq.b r4,r63,r6 |
SHHI r6,r7,r6 |
bnei/u r6,0,tr1 // shortstring |
pta/l no_lddst, tr2 |
ori r3,-8,r23 |
sub r2, r23, r0 |
sub r3, r2, r21 |
addi r21, 8, r20 |
ldx.q r0, r21, r5 |
pta/l loop, tr0 |
ori r2,-8,r22 |
mcmpeq.b r5, r63, r6 |
bgt/u r22, r23, tr2 // no_lddst |
|
// r22 < r23 : Need to do a load from the destination. |
// r22 == r23 : Doesn't actually need to load from destination, |
// but still can be handled here. |
ldlo.q r2, 0, r9 |
movi -1, r8 |
SHLO r8, r7, r8 |
mcmv r4, r8, r9 |
stlo.q r2, 0, r9 |
beqi/l r6, 0, tr0 // loop |
|
add r5, r63, r4 |
addi r0, 8, r0 |
blink tr1, r63 // shortstring |
no_lddst: |
// r22 > r23: note that for r22 == r23 the sthi.q would clobber |
// bytes before the destination region. |
stlo.q r2, 0, r4 |
SHHI r4, r7, r4 |
sthi.q r0, -1, r4 |
beqi/l r6, 0, tr0 // loop |
|
add r5, r63, r4 |
addi r0, 8, r0 |
shortstring: |
#ifndef __LITTLE_ENDIAN__ |
pta/l shortstring2,tr1 |
byterev r4,r4 |
#endif |
shortstring2: |
st.b r0,-8,r4 |
andi r4,0xff,r5 |
shlri r4,8,r4 |
addi r0,1,r0 |
bnei/l r5,0,tr1 |
blink tr4,r63 // return |
|
.balign 8 |
loop: |
stlo.q r0, 0, r5 |
ldx.q r0, r20, r4 |
addi r0, 16, r0 |
sthi.q r0, -9, r5 |
mcmpeq.b r4, r63, r6 |
bnei/u r6, 0, tr1 // shortstring |
ldx.q r0, r21, r5 |
stlo.q r0, -8, r4 |
sthi.q r0, -1, r4 |
mcmpeq.b r5, r63, r6 |
beqi/l r6, 0, tr0 // loop |
|
add r5, r63, r4 |
addi r0, 8, r0 |
blink tr1, r63 // shortstring |
|
.size strcpy, . - strcpy |
|
/sh64/memcpy.S
0,0 → 1,202
/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */ |
/* Modified by SuperH, Inc. September 2003 */ |
! |
! Fast SH memcpy |
! |
! by Toshiyasu Morita (tm@netcom.com) |
! hacked by J"orn Rernnecke (joern.rennecke@superh.com) ("o for o-umlaut) |
! SH5 code Copyright 2002 SuperH Ltd. |
! |
! Entry: ARG0: destination pointer |
! ARG1: source pointer |
! ARG2: byte count |
! |
! Exit: RESULT: destination pointer |
! any other registers in the range r0-r7: trashed |
! |
! Notes: Usually one wants to do small reads and write a longword, but |
! unfortunately it is difficult in some cases to concatanate bytes |
! into a longword on the SH, so this does a longword read and small |
! writes. |
! |
! This implementation makes two assumptions about how it is called: |
! |
! 1.: If the byte count is nonzero, the address of the last byte to be |
! copied is unsigned greater than the address of the first byte to |
! be copied. This could be easily swapped for a signed comparison, |
! but the algorithm used needs some comparison. |
! |
! 2.: When there are two or three bytes in the last word of an 11-or-more |
! bytes memory chunk to b copied, the rest of the word can be read |
! without side effects. |
! This could be easily changed by increasing the minumum size of |
! a fast memcpy and the amount subtracted from r7 before L_2l_loop be 2, |
! however, this would cost a few extra cyles on average. |
! For SHmedia, the assumption is that any quadword can be read in its |
! enirety if at least one byte is included in the copy. |
! |
|
.section .text..SHmedia32,"ax" |
.globl memcpy |
.type memcpy, @function |
|
.align 5 |
memcpy: |
|
#define LDUAQ(P,O,D0,D1) ldlo.q P,O,D0; ldhi.q P,O+7,D1 |
#define STUAQ(P,O,D0,D1) stlo.q P,O,D0; sthi.q P,O+7,D1 |
#define LDUAL(P,O,D0,D1) ldlo.l P,O,D0; ldhi.l P,O+3,D1 |
#define STUAL(P,O,D0,D1) stlo.l P,O,D0; sthi.l P,O+3,D1 |
|
ld.b r3,0,r63 |
pta/l Large,tr0 |
movi 25,r0 |
bgeu/u r4,r0,tr0 |
nsb r4,r0 |
shlli r0,5,r0 |
movi (L1-L0+63*32 + 1) & 0xffff,r1 |
sub r1, r0, r0 |
L0: ptrel r0,tr0 |
add r2,r4,r5 |
ptabs r18,tr1 |
add r3,r4,r6 |
blink tr0,r63 |
|
/* Rearranged to make cut2 safe */ |
.balign 8 |
L4_7: /* 4..7 byte memcpy cntd. */ |
stlo.l r2, 0, r0 |
or r6, r7, r6 |
sthi.l r5, -1, r6 |
stlo.l r5, -4, r6 |
blink tr1,r63 |
|
.balign 8 |
L1: /* 0 byte memcpy */ |
nop |
blink tr1,r63 |
nop |
nop |
nop |
nop |
|
L2_3: /* 2 or 3 byte memcpy cntd. */ |
st.b r5,-1,r6 |
blink tr1,r63 |
|
/* 1 byte memcpy */ |
ld.b r3,0,r0 |
st.b r2,0,r0 |
blink tr1,r63 |
|
L8_15: /* 8..15 byte memcpy cntd. */ |
stlo.q r2, 0, r0 |
or r6, r7, r6 |
sthi.q r5, -1, r6 |
stlo.q r5, -8, r6 |
blink tr1,r63 |
|
/* 2 or 3 byte memcpy */ |
ld.b r3,0,r0 |
ld.b r2,0,r63 |
ld.b r3,1,r1 |
st.b r2,0,r0 |
pta/l L2_3,tr0 |
ld.b r6,-1,r6 |
st.b r2,1,r1 |
blink tr0, r63 |
|
/* 4 .. 7 byte memcpy */ |
LDUAL (r3, 0, r0, r1) |
pta L4_7, tr0 |
ldlo.l r6, -4, r7 |
or r0, r1, r0 |
sthi.l r2, 3, r0 |
ldhi.l r6, -1, r6 |
blink tr0, r63 |
|
/* 8 .. 15 byte memcpy */ |
LDUAQ (r3, 0, r0, r1) |
pta L8_15, tr0 |
ldlo.q r6, -8, r7 |
or r0, r1, r0 |
sthi.q r2, 7, r0 |
ldhi.q r6, -1, r6 |
blink tr0, r63 |
|
/* 16 .. 24 byte memcpy */ |
LDUAQ (r3, 0, r0, r1) |
LDUAQ (r3, 8, r8, r9) |
or r0, r1, r0 |
sthi.q r2, 7, r0 |
or r8, r9, r8 |
sthi.q r2, 15, r8 |
ldlo.q r6, -8, r7 |
ldhi.q r6, -1, r6 |
stlo.q r2, 8, r8 |
stlo.q r2, 0, r0 |
or r6, r7, r6 |
sthi.q r5, -1, r6 |
stlo.q r5, -8, r6 |
blink tr1,r63 |
|
Large: |
ld.b r2, 0, r63 |
pta/l Loop_ua, tr1 |
ori r3, -8, r7 |
sub r2, r7, r22 |
sub r3, r2, r6 |
add r2, r4, r5 |
ldlo.q r3, 0, r0 |
addi r5, -16, r5 |
movi 64+8, r27 // could subtract r7 from that. |
stlo.q r2, 0, r0 |
sthi.q r2, 7, r0 |
ldx.q r22, r6, r0 |
bgtu/l r27, r4, tr1 |
|
addi r5, -48, r27 |
pta/l Loop_line, tr0 |
addi r6, 64, r36 |
addi r6, -24, r19 |
addi r6, -16, r20 |
addi r6, -8, r21 |
|
Loop_line: |
ldx.q r22, r36, r63 |
alloco r22, 32 |
addi r22, 32, r22 |
ldx.q r22, r19, r23 |
sthi.q r22, -25, r0 |
ldx.q r22, r20, r24 |
ldx.q r22, r21, r25 |
stlo.q r22, -32, r0 |
ldx.q r22, r6, r0 |
sthi.q r22, -17, r23 |
sthi.q r22, -9, r24 |
sthi.q r22, -1, r25 |
stlo.q r22, -24, r23 |
stlo.q r22, -16, r24 |
stlo.q r22, -8, r25 |
bgeu r27, r22, tr0 |
|
Loop_ua: |
addi r22, 8, r22 |
sthi.q r22, -1, r0 |
stlo.q r22, -8, r0 |
ldx.q r22, r6, r0 |
bgtu/l r5, r22, tr1 |
|
add r3, r4, r7 |
ldlo.q r7, -8, r1 |
sthi.q r22, 7, r0 |
ldhi.q r7, -1, r7 |
ptabs r18,tr1 |
stlo.q r22, 0, r0 |
or r1, r7, r1 |
sthi.q r5, 15, r1 |
stlo.q r5, 8, r1 |
blink tr1, r63 |
|
.size memcpy, . - memcpy |
|
/sh64/memset.S
0,0 → 1,92
/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */ |
/* Modified by SuperH, Inc. September 2003 */ |
! |
! Fast SH memset |
! |
! by Toshiyasu Morita (tm@netcom.com) |
! |
! SH5 code by J"orn Rennecke (joern.rennecke@superh.com) |
! Copyright 2002 SuperH Ltd. |
! |
|
#ifdef __LITTLE_ENDIAN__ |
#define SHHI shlld |
#define SHLO shlrd |
#else |
#define SHHI shlrd |
#define SHLO shlld |
#endif |
|
.section .text..SHmedia32,"ax" |
.globl memset |
.type memset, @function |
|
.align 5 |
|
memset: |
pta/l multiquad, tr0 |
andi r2, 7, r22 |
ptabs r18, tr2 |
mshflo.b r3,r3,r3 |
add r4, r22, r23 |
mperm.w r3, r63, r3 // Fill pattern now in every byte of r3 |
|
movi 8, r9 |
bgtu/u r23, r9, tr0 // multiquad |
|
beqi/u r4, 0, tr2 // Return with size 0 - ensures no mem accesses |
ldlo.q r2, 0, r7 |
shlli r4, 2, r4 |
movi -1, r8 |
SHHI r8, r4, r8 |
SHHI r8, r4, r8 |
mcmv r7, r8, r3 |
stlo.q r2, 0, r3 |
blink tr2, r63 |
|
multiquad: |
pta/l lastquad, tr0 |
stlo.q r2, 0, r3 |
shlri r23, 3, r24 |
add r2, r4, r5 |
beqi/u r24, 1, tr0 // lastquad |
pta/l loop, tr1 |
sub r2, r22, r25 |
andi r5, -8, r20 // calculate end address and |
addi r20, -7*8, r8 // loop end address; This might overflow, so we need |
// to use a different test before we start the loop |
bge/u r24, r9, tr1 // loop |
st.q r25, 8, r3 |
st.q r20, -8, r3 |
shlri r24, 1, r24 |
beqi/u r24, 1, tr0 // lastquad |
st.q r25, 16, r3 |
st.q r20, -16, r3 |
beqi/u r24, 2, tr0 // lastquad |
st.q r25, 24, r3 |
st.q r20, -24, r3 |
lastquad: |
sthi.q r5, -1, r3 |
blink tr2,r63 |
|
loop: |
!!! alloco r25, 32 // QQQ comment out for short-term fix to SHUK #3895. |
// QQQ commenting out is locically correct, but sub-optimal |
// QQQ Sean McGoogan - 4th April 2003. |
st.q r25, 8, r3 |
st.q r25, 16, r3 |
st.q r25, 24, r3 |
st.q r25, 32, r3 |
addi r25, 32, r25 |
bgeu/l r8, r25, tr1 // loop |
|
st.q r20, -40, r3 |
st.q r20, -32, r3 |
st.q r20, -24, r3 |
st.q r20, -16, r3 |
st.q r20, -8, r3 |
sthi.q r5, -1, r3 |
blink tr2,r63 |
|
.size memset, . - memset |
|
/sh64/Makefile
0,0 → 1,38
# Makefile for uClibc's sh64 optimized string routines |
# |
# Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> |
# |
# This program is free software; you can redistribute it and/or modify it under |
# the terms of the GNU Library General Public License as published by the Free |
# Software Foundation; either version 2 of the License, or (at your option) any |
# later version. |
# |
# This program is distributed in the hope that it will be useful, but WITHOUT |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more |
# details. |
# |
# You should have received a copy of the GNU Library General Public License |
# along with this program; if not, write to the Free Software Foundation, Inc., |
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
TOPDIR=../../../ |
include $(TOPDIR)Rules.mak |
|
SSRC= memcpy.S memset.S strcpy.S |
SOBJS=$(patsubst %.S,%.o, $(SSRC)) |
|
all: $(SOBJS) $(LIBC) |
|
$(LIBC): ar-target |
|
ar-target: $(SOBJS) |
$(AR) $(ARFLAGS) $(LIBC) $(SOBJS) |
|
$(SOBJS): %.o : %.S |
$(CC) $(CFLAGS) -c $< -o $@ |
$(STRIPTOOL) -x -R .note -R .comment $*.o |
|
clean: |
$(RM) *.[oa] *~ core |
|
/i386/string.c
0,0 → 1,322
/* |
* This string-include defines all string functions as inline |
* functions. Use gcc. It also assumes ds=es=data space, this should be |
* normal. Most of the string-functions are rather heavily hand-optimized, |
* see especially strtok,strstr,str[c]spn. They should work, but are not |
* very easy to understand. Everything is done entirely within the register |
* set, making the functions fast and clean. String instructions have been |
* used through-out, making for "slightly" unclear code :-) |
* |
* NO Copyright (C) 1991, 1992 Linus Torvalds, |
* consider these trivial functions to be PD. |
* |
* Modified for uClibc by Erik Andersen <andersen@codepoet.org> |
* These make no attempt to use nifty things like mmx/3dnow/etc. |
* These are not inline, and will therefore not be as fast as |
* modifying the headers to use inlines (and cannot therefore |
* do tricky things when dealing with const memory). But they |
* should (I hope!) be faster than their generic equivalents.... |
* |
* More importantly, these should provide a good example for |
* others to follow when adding arch specific optimizations. |
* -Erik |
*/ |
|
#define _STDIO_UTILITY |
#define _GNU_SOURCE |
#include <string.h> |
#include <locale.h> /* for __LOCALE_C_ONLY */ |
|
#ifdef L_strcpy |
char * strcpy(char * dest, const char * src) |
{ |
int d0, d1, d2; |
__asm__ __volatile__( |
"1:\tlodsb\n\t" |
"stosb\n\t" |
"testb %%al,%%al\n\t" |
"jne 1b" |
: "=&S" (d0), "=&D" (d1), "=&a" (d2) |
:"0" (src),"1" (dest) : "memory"); |
return dest; |
} |
#endif |
|
|
#ifdef L_strncpy |
char * strncpy(char * dest, const char * src, size_t count) |
{ |
int d0, d1, d2, d3; |
__asm__ __volatile__( |
"1:\tdecl %2\n\t" |
"js 2f\n\t" |
"lodsb\n\t" |
"stosb\n\t" |
"testb %%al,%%al\n\t" |
"jne 1b\n\t" |
"rep\n\t" |
"stosb\n" |
"2:" |
: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3) |
:"0" (src),"1" (dest),"2" (count) : "memory"); |
return dest; |
} |
#endif |
|
|
#ifdef L_strcat |
char *strcat(char * dest, const char * src) |
{ |
int d0, d1, d2, d3; |
__asm__ __volatile__( |
"repne\n\t" |
"scasb\n\t" |
"decl %1\n" |
"1:\tlodsb\n\t" |
"stosb\n\t" |
"testb %%al,%%al\n\t" |
"jne 1b" |
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) |
: "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory"); |
return dest; |
} |
#endif |
|
|
#ifdef L_strncat |
char *strncat(char * dest, |
const char * src, size_t count) |
{ |
int d0, d1, d2, d3; |
__asm__ __volatile__( |
"repne\n\t" |
"scasb\n\t" |
"decl %1\n\t" |
"movl %8,%3\n" |
"1:\tdecl %3\n\t" |
"js 2f\n\t" |
"lodsb\n\t" |
"stosb\n\t" |
"testb %%al,%%al\n\t" |
"jne 1b\n" |
"2:\txorl %2,%2\n\t" |
"stosb" |
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) |
: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) |
: "memory"); |
return dest; |
} |
#endif |
|
|
#ifdef L_strcmp |
int strcmp(const char *cs, const char *ct) |
{ |
int d0, d1; |
register int __res; |
__asm__ __volatile__( |
"1:\tlodsb\n\t" |
"scasb\n\t" |
"jne 2f\n\t" |
"testb %%al,%%al\n\t" |
"jne 1b\n\t" |
"xorl %%eax,%%eax\n\t" |
"jmp 3f\n" |
"2:\tsbbl %%eax,%%eax\n\t" |
"orb $1,%%al\n" |
"3:" |
:"=a" (__res), "=&S" (d0), "=&D" (d1) |
:"1" (cs),"2" (ct)); |
return __res; |
} |
#ifdef __LOCALE_C_ONLY |
weak_alias(strcmp,strcoll); |
#endif /* __LOCALE_C_ONLY */ |
#endif |
|
|
#ifdef L_strncmp |
int strncmp(const char *cs, const char *ct, size_t count) |
{ |
register int __res; |
int d0, d1, d2; |
__asm__ __volatile__( |
"1:\tdecl %3\n\t" |
"js 2f\n\t" |
"lodsb\n\t" |
"scasb\n\t" |
"jne 3f\n\t" |
"testb %%al,%%al\n\t" |
"jne 1b\n" |
"2:\txorl %%eax,%%eax\n\t" |
"jmp 4f\n" |
"3:\tsbbl %%eax,%%eax\n\t" |
"orb $1,%%al\n" |
"4:" |
:"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) |
:"1" (cs),"2" (ct),"3" (count)); |
return __res; |
} |
#endif |
|
|
#ifdef L_strchr |
char * strchr(const char *s, int c) |
{ |
int d0; |
register char * __res; |
__asm__ __volatile__( |
"movb %%al,%%ah\n" |
"1:\tlodsb\n\t" |
"cmpb %%ah,%%al\n\t" |
"je 2f\n\t" |
"testb %%al,%%al\n\t" |
"jne 1b\n\t" |
"movl $1,%1\n" |
"2:\tmovl %1,%0\n\t" |
"decl %0" |
:"=a" (__res), "=&S" (d0) : "1" (s),"0" (c)); |
return __res; |
} |
weak_alias(strchr,index); |
#endif |
|
|
#ifdef L_strrchr |
char *strrchr(const char *s, int c) |
{ |
int d0, d1; |
register char * __res; |
__asm__ __volatile__( |
"movb %%al,%%ah\n" |
"1:\tlodsb\n\t" |
"cmpb %%ah,%%al\n\t" |
"jne 2f\n\t" |
"leal -1(%%esi),%0\n" |
"2:\ttestb %%al,%%al\n\t" |
"jne 1b" |
:"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c)); |
return __res; |
} |
weak_alias(strrchr,rindex); |
#endif |
|
|
|
#ifdef L_strlen |
size_t strlen(const char *s) |
{ |
int d0; |
register int __res; |
__asm__ __volatile__( |
"repne\n\t" |
"scasb\n\t" |
"notl %0\n\t" |
"decl %0" |
:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff)); |
return __res; |
} |
#endif |
|
|
#ifdef L_strnlen |
size_t strnlen(const char *s, size_t count) |
{ |
int d0; |
register int __res; |
__asm__ __volatile__( |
"movl %2,%0\n\t" |
"jmp 2f\n" |
"1:\tcmpb $0,(%0)\n\t" |
"je 3f\n\t" |
"incl %0\n" |
"2:\tdecl %1\n\t" |
"cmpl $-1,%1\n\t" |
"jne 1b\n" |
"3:\tsubl %2,%0" |
:"=a" (__res), "=&d" (d0) |
:"c" (s),"1" (count)); |
return __res; |
} |
#endif |
|
|
#ifdef L_memcpy |
void *memcpy(void * to, const void * from, size_t n) |
{ |
int d0, d1, d2; |
__asm__ __volatile__( |
"rep ; movsl\n\t" |
"testb $2,%b4\n\t" |
"je 1f\n\t" |
"movsw\n" |
"1:\ttestb $1,%b4\n\t" |
"je 2f\n\t" |
"movsb\n" |
"2:" |
: "=&c" (d0), "=&D" (d1), "=&S" (d2) |
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) |
: "memory"); |
return (to); |
} |
#endif |
|
|
#ifdef L_memmove |
void *memmove(void *dest, const void *src, size_t n) |
{ |
int d0, d1, d2; |
if (dest<src) |
__asm__ __volatile__( |
"rep\n\t" |
"movsb" |
: "=&c" (d0), "=&S" (d1), "=&D" (d2) |
:"0" (n),"1" (src),"2" (dest) |
: "memory"); |
else |
__asm__ __volatile__( |
"std\n\t" |
"rep\n\t" |
"movsb\n\t" |
"cld" |
: "=&c" (d0), "=&S" (d1), "=&D" (d2) |
:"0" (n), |
"1" (n-1+(const char *)src), |
"2" (n-1+(char *)dest) |
:"memory"); |
return dest; |
} |
#endif |
|
#ifdef L_memchr |
void *memchr(const void *cs, int c, size_t count) |
{ |
int d0; |
register void * __res; |
if (!count) |
return NULL; |
__asm__ __volatile__( |
"repne\n\t" |
"scasb\n\t" |
"je 1f\n\t" |
"movl $1,%0\n" |
"1:\tdecl %0" |
:"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count)); |
return __res; |
} |
#endif |
|
#ifdef L_memset |
void *memset(void *s, int c, size_t count) |
{ |
int d0, d1; |
__asm__ __volatile__( |
"rep\n\t" |
"stosb" |
: "=&c" (d0), "=&D" (d1) |
:"a" (c),"1" (s),"0" (count) |
:"memory"); |
return s; |
} |
#endif |
|
/i386/Makefile
0,0 → 1,45
# Makefile for uClibc |
# |
# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org> |
# |
# This program is free software; you can redistribute it and/or modify it under |
# the terms of the GNU Library General Public License as published by the Free |
# Software Foundation; either version 2 of the License, or (at your option) any |
# later version. |
# |
# This program is distributed in the hope that it will be useful, but WITHOUT |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more |
# details. |
# |
# You should have received a copy of the GNU Library General Public License |
# along with this program; if not, write to the Free Software Foundation, Inc., |
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
TOPDIR=../../../ |
include $(TOPDIR)Rules.mak |
|
MSRC= string.c |
MOBJ= strcpy.o strncpy.o strcat.o strncat.o strcmp.o \ |
strncmp.o strchr.o strrchr.o strlen.o strnlen.o \ |
memcpy.o memmove.o memchr.o memset.o |
OBJS=$(MOBJ) |
|
all: $(OBJS) $(LIBC) |
|
$(LIBC): ar-target |
|
ar-target: $(OBJS) |
$(AR) $(ARFLAGS) $(LIBC) $(OBJS) |
|
$(MOBJ): $(MSRC) |
$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o |
$(STRIPTOOL) -x -R .note -R .comment $*.o |
|
$(COBJS): %.o : %.c |
$(CC) $(CFLAGS) -c $< -o $@ |
$(STRIPTOOL) -x -R .note -R .comment $*.o |
|
clean: |
$(RM) *.[oa] *~ core |
|
/Makefile
0,0 → 1,102
# Makefile for uClibc |
# |
# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org> |
# |
# This program is free software; you can redistribute it and/or modify it under |
# the terms of the GNU Library General Public License as published by the Free |
# Software Foundation; either version 2 of the License, or (at your option) any |
# later version. |
# |
# This program is distributed in the hope that it will be useful, but WITHOUT |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more |
# details. |
# |
# You should have received a copy of the GNU Library General Public License |
# along with this program; if not, write to the Free Software Foundation, Inc., |
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
TOPDIR=../../ |
include $(TOPDIR)Rules.mak |
|
DIRS= |
ifeq ($(TARGET_ARCH),$(wildcard $(TARGET_ARCH))) |
DIRS = $(TARGET_ARCH) |
endif |
ALL_SUBDIRS = i386 arm sh64 |
|
MSRC= wstring.c |
MOBJ= basename.o bcopy.o bzero.o dirname.o ffs.o memccpy.o memchr.o memcmp.o \ |
memcpy.o memmove.o mempcpy.o memrchr.o memset.o rawmemchr.o stpcpy.o \ |
stpncpy.o strcasecmp.o strcasestr.o strcat.o strchrnul.o strchr.o \ |
strcmp.o strcpy.o strcspn.o strdup.o strlen.o strncasecmp.o strncat.o \ |
strncmp.o strncpy.o strndup.o strnlen.o strpbrk.o strrchr.o strsep.o \ |
strspn.o strstr.o strtok.o strtok_r.o strerror.o _susv3_strerror_r.o \ |
_string_syserrmsgs.o _glibc_strerror_r.o \ |
_string_syssigmsgs.o sys_siglist.o strsignal.o psignal.o \ |
__xpg_basename.o strlcat.o strlcpy.o sys_errlist.o memmem.o |
|
MOBJW= wcscasecmp.o wcscat.o wcschrnul.o wcschr.o wcscmp.o wcscpy.o wcscspn.o \ |
wcsdup.o wcslen.o wcsncasecmp.o wcsncat.o wcsncmp.o wcsncpy.o \ |
wcsnlen.o wcspbrk.o wcsrchr.o wcsspn.o wcsstr.o wcstok.o wmemchr.o \ |
wmemcmp.o wmemcpy.o wmemmove.o wmempcpy.o wmemset.o wcpcpy.o wcpncpy.o \ |
__wcslcpy.o \ |
wcsxfrm.o strxfrm.o # wcscoll strcoll.o |
|
MOBJx= |
MOBJWx= |
|
ifeq ($(UCLIBC_HAS_XLOCALE),y) |
MOBJx += strcasecmp_l.o strncasecmp_l.o |
MOBJWx += wcscasecmp_l.o wcsncasecmp_l.o wcsxfrm_l.o strxfrm_l.o |
endif |
|
#ffsl ffsll |
|
OBJS=$(MOBJ) $(MOBJx) |
|
ifeq ($(UCLIBC_HAS_WCHAR),y) |
OBJS += $(MOBJW) $(MOBJWx) |
endif |
|
all: $(LIBC) subdirs |
|
$(LIBC): ar-target |
|
ar-target: $(OBJS) |
$(AR) $(ARFLAGS) $(LIBC) $(OBJS) |
|
$(MOBJ): $(MSRC) |
$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o |
$(STRIPTOOL) -x -R .note -R .comment $*.o |
|
$(MOBJx): $(MSRC) |
$(CC) $(CFLAGS) -DL_$* -D__UCLIBC_DO_XLOCALE $< -c -o $*.o |
$(STRIPTOOL) -x -R .note -R .comment $*.o |
|
$(MOBJW): $(MSRC) |
$(CC) $(CFLAGS) -DWANT_WIDE -DL_$* $< -c -o $*.o |
$(STRIPTOOL) -x -R .note -R .comment $*.o |
|
$(MOBJWx): $(MSRC) |
$(CC) $(CFLAGS) -DWANT_WIDE -DL_$* -D__UCLIBC_DO_XLOCALE $< -c -o $*.o |
$(STRIPTOOL) -x -R .note -R .comment $*.o |
|
$(COBJS): %.o : %.c |
$(CC) $(CFLAGS) -c $< -o $@ |
$(STRIPTOOL) -x -R .note -R .comment $*.o |
|
clean: subdirs_clean |
$(RM) *.[oa] *~ core |
|
subdirs: $(patsubst %, _dir_%, $(DIRS)) |
subdirs_clean: $(patsubst %, _dirclean_%, $(ALL_SUBDIRS)) |
|
$(patsubst %, _dir_%, $(DIRS)) : $(OBJS) |
$(MAKE) -C $(patsubst _dir_%, %, $@) |
|
$(patsubst %, _dirclean_%, $(ALL_SUBDIRS)) : dummy |
$(MAKE) -C $(patsubst _dirclean_%, %, $@) clean |
|
.PHONY: dummy |
|
/.indent.pro
0,0 → 1,33
--blank-lines-after-declarations |
--blank-lines-after-procedures |
--break-before-boolean-operator |
--no-blank-lines-after-commas |
--braces-on-if-line |
--braces-on-struct-decl-line |
--comment-indentation25 |
--declaration-comment-column25 |
--no-comment-delimiters-on-blank-lines |
--cuddle-else |
--continuation-indentation4 |
--case-indentation0 |
--else-endif-column33 |
--space-after-cast |
--line-comments-indentation0 |
--declaration-indentation1 |
--dont-format-first-column-comments |
--dont-format-comments |
--honour-newlines |
--indent-level4 |
/* changed from 0 to 4 */ |
--parameter-indentation4 |
--line-length78 /* changed from 75 */ |
--continue-at-parentheses |
--no-space-after-function-call-names |
--dont-break-procedure-type |
--dont-star-comments |
--leave-optional-blank-lines |
--dont-space-special-semicolon |
--tab-size4 |
/* additions by Mark */ |
--case-brace-indentation0 |
--leave-preprocessor-space |
/wstring.c
0,0 → 1,2987
/* Copyright (C) 2002 Manuel Novoa III |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Library General Public |
* License as published by the Free Software Foundation; either |
* version 2 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Library General Public License for more details. |
* |
* You should have received a copy of the GNU Library General Public |
* License along with this library; if not, write to the Free |
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
/* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! |
* |
* Besides uClibc, I'm using this code in my libc for elks, which is |
* a 16-bit environment with a fairly limited compiler. It would make |
* things much easier for me if this file isn't modified unnecessarily. |
* In particular, please put any new or replacement functions somewhere |
* else, and modify the makefile to use your version instead. |
* Thanks. Manuel |
* |
* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */ |
|
/* Dec 20, 2002 |
* Initial test implementation of strcoll, strxfrm, wcscoll, and wcsxfrm. |
* The code needs to be cleaned up a good bit, but I'd like to see people |
* test it out. |
* |
* Sep 11, 2003 |
* Patch by Atsushi Nemoto <anemo@mba.ocn.ne.jp> to do arch-required |
* mapping of signal strings (alpha, mips, hppa, sparc). |
*/ |
|
#define _STDIO_UTILITY |
#define _GNU_SOURCE |
#include <string.h> |
#include <strings.h> |
#include <stdio.h> |
#include <limits.h> |
#include <ctype.h> |
#include <stdlib.h> |
#include <errno.h> |
#include <signal.h> |
#include <assert.h> |
#include <locale.h> |
|
#ifdef WANT_WIDE |
#include <wchar.h> |
#include <wctype.h> |
#include <bits/uClibc_uwchar.h> |
|
#define Wvoid wchar_t |
#define Wchar wchar_t |
#define Wuchar __uwchar_t |
#define Wint wchar_t |
|
#else |
|
#define Wvoid void |
#define Wchar char |
typedef unsigned char __string_uchar_t; |
#define Wuchar __string_uchar_t |
#define Wint int |
|
#endif |
|
/**********************************************************************/ |
/* NOTE: If we ever do internationalized syserr messages, this will |
* have to be changed! */ |
|
#define _SYS_NERR 125 |
#if defined(__mips__) || defined(__sparc__) |
/* sparce and mips have an extra error entry, as EDEADLK and EDEADLOCK have |
* different meanings on those platforms. */ |
#undef _SYS_NERR |
#define _SYS_NERR 126 |
#endif |
|
#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__ |
#define _SYS_ERRMSG_MAXLEN 50 |
#else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */ |
#define _SYS_ERRMSG_MAXLEN 0 |
#endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */ |
|
|
extern const char _string_syserrmsgs[]; |
|
#define _SYS_NSIG 32 |
|
#ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__ |
#define _SYS_SIGMSG_MAXLEN 25 |
#else /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */ |
#define _SYS_SIGMSG_MAXLEN 0 |
#endif /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */ |
|
extern const char _string_syssigmsgs[]; |
|
|
#if _SYS_ERRMSG_MAXLEN < __UIM_BUFLEN_INT + 14 |
#define _STRERROR_BUFSIZE (__UIM_BUFLEN_INT + 14) |
#else |
#define _STRERROR_BUFSIZE _SYS_ERRMSG_MAXLEN |
#endif |
|
#if _SYS_SIGMSG_MAXLEN < __UIM_BUFLEN_INT + 15 |
#define _STRSIGNAL_BUFSIZE (__UIM_BUFLEN_INT + 15) |
#else |
#define _STRSIGNAL_BUFSIZE _SYS_SIGMSG_MAXLEN |
#endif |
|
/**********************************************************************/ |
#if defined(L__string_syserrmsgs) && defined(__UCLIBC_HAS_ERRNO_MESSAGES__) |
|
const char _string_syserrmsgs[] = { |
/* 0: 0, 8 */ "Success\0" |
/* 1: 8, 24 */ "Operation not permitted\0" |
/* 2: 32, 26 */ "No such file or directory\0" |
/* 3: 58, 16 */ "No such process\0" |
/* 4: 74, 24 */ "Interrupted system call\0" |
/* 5: 98, 19 */ "Input/output error\0" |
/* 6: 117, 26 */ "No such device or address\0" |
/* 7: 143, 23 */ "Argument list too long\0" |
/* 8: 166, 18 */ "Exec format error\0" |
/* 9: 184, 20 */ "Bad file descriptor\0" |
/* 10: 204, 19 */ "No child processes\0" |
/* 11: 223, 33 */ "Resource temporarily unavailable\0" |
/* 12: 256, 23 */ "Cannot allocate memory\0" |
/* 13: 279, 18 */ "Permission denied\0" |
/* 14: 297, 12 */ "Bad address\0" |
/* 15: 309, 22 */ "Block device required\0" |
/* 16: 331, 24 */ "Device or resource busy\0" |
/* 17: 355, 12 */ "File exists\0" |
/* 18: 367, 26 */ "Invalid cross-device link\0" |
/* 19: 393, 15 */ "No such device\0" |
/* 20: 408, 16 */ "Not a directory\0" |
/* 21: 424, 15 */ "Is a directory\0" |
/* 22: 439, 17 */ "Invalid argument\0" |
/* 23: 456, 30 */ "Too many open files in system\0" |
/* 24: 486, 20 */ "Too many open files\0" |
/* 25: 506, 31 */ "Inappropriate ioctl for device\0" |
/* 26: 537, 15 */ "Text file busy\0" |
/* 27: 552, 15 */ "File too large\0" |
/* 28: 567, 24 */ "No space left on device\0" |
/* 29: 591, 13 */ "Illegal seek\0" |
/* 30: 604, 22 */ "Read-only file system\0" |
/* 31: 626, 15 */ "Too many links\0" |
/* 32: 641, 12 */ "Broken pipe\0" |
/* 33: 653, 33 */ "Numerical argument out of domain\0" |
/* 34: 686, 30 */ "Numerical result out of range\0" |
/* 35: 716, 26 */ "Resource deadlock avoided\0" |
/* 36: 742, 19 */ "File name too long\0" |
/* 37: 761, 19 */ "No locks available\0" |
/* 38: 780, 25 */ "Function not implemented\0" |
/* 39: 805, 20 */ "Directory not empty\0" |
/* 40: 825, 34 */ "Too many levels of symbolic links\0" |
/* 41: 859, 1 */ "\0" |
/* 42: 860, 27 */ "No message of desired type\0" |
/* 43: 887, 19 */ "Identifier removed\0" |
/* 44: 906, 28 */ "Channel number out of range\0" |
/* 45: 934, 25 */ "Level 2 not synchronized\0" |
/* 46: 959, 15 */ "Level 3 halted\0" |
/* 47: 974, 14 */ "Level 3 reset\0" |
/* 48: 988, 25 */ "Link number out of range\0" |
/* 49: 1013, 29 */ "Protocol driver not attached\0" |
/* 50: 1042, 27 */ "No CSI structure available\0" |
/* 51: 1069, 15 */ "Level 2 halted\0" |
/* 52: 1084, 17 */ "Invalid exchange\0" |
/* 53: 1101, 27 */ "Invalid request descriptor\0" |
/* 54: 1128, 14 */ "Exchange full\0" |
/* 55: 1142, 9 */ "No anode\0" |
/* 56: 1151, 21 */ "Invalid request code\0" |
/* 57: 1172, 13 */ "Invalid slot\0" |
/* 58: 1185, 1 */ "\0" |
/* 59: 1186, 21 */ "Bad font file format\0" |
/* 60: 1207, 20 */ "Device not a stream\0" |
/* 61: 1227, 18 */ "No data available\0" |
/* 62: 1245, 14 */ "Timer expired\0" |
/* 63: 1259, 25 */ "Out of streams resources\0" |
/* 64: 1284, 30 */ "Machine is not on the network\0" |
/* 65: 1314, 22 */ "Package not installed\0" |
/* 66: 1336, 17 */ "Object is remote\0" |
/* 67: 1353, 22 */ "Link has been severed\0" |
/* 68: 1375, 16 */ "Advertise error\0" |
/* 69: 1391, 14 */ "Srmount error\0" |
/* 70: 1405, 28 */ "Communication error on send\0" |
/* 71: 1433, 15 */ "Protocol error\0" |
/* 72: 1448, 19 */ "Multihop attempted\0" |
/* 73: 1467, 19 */ "RFS specific error\0" |
/* 74: 1486, 12 */ "Bad message\0" |
/* 75: 1498, 38 */ "Value too large for defined data type\0" |
/* 76: 1536, 27 */ "Name not unique on network\0" |
/* 77: 1563, 29 */ "File descriptor in bad state\0" |
/* 78: 1592, 23 */ "Remote address changed\0" |
/* 79: 1615, 39 */ "Can not access a needed shared library\0" |
/* 80: 1654, 37 */ "Accessing a corrupted shared library\0" |
/* 81: 1691, 32 */ ".lib section in a.out corrupted\0" |
/* 82: 1723, 48 */ "Attempting to link in too many shared libraries\0" |
/* 83: 1771, 38 */ "Cannot exec a shared library directly\0" |
/* 84: 1809, 50 */ "Invalid or incomplete multibyte or wide character\0" |
/* 85: 1859, 44 */ "Interrupted system call should be restarted\0" |
/* 86: 1903, 19 */ "Streams pipe error\0" |
/* 87: 1922, 15 */ "Too many users\0" |
/* 88: 1937, 31 */ "Socket operation on non-socket\0" |
/* 89: 1968, 29 */ "Destination address required\0" |
/* 90: 1997, 17 */ "Message too long\0" |
/* 91: 2014, 31 */ "Protocol wrong type for socket\0" |
/* 92: 2045, 23 */ "Protocol not available\0" |
/* 93: 2068, 23 */ "Protocol not supported\0" |
/* 94: 2091, 26 */ "Socket type not supported\0" |
/* 95: 2117, 24 */ "Operation not supported\0" |
/* 96: 2141, 30 */ "Protocol family not supported\0" |
/* 97: 2171, 41 */ "Address family not supported by protocol\0" |
/* 98: 2212, 23 */ "Address already in use\0" |
/* 99: 2235, 32 */ "Cannot assign requested address\0" |
/* 100: 2267, 16 */ "Network is down\0" |
/* 101: 2283, 23 */ "Network is unreachable\0" |
/* 102: 2306, 36 */ "Network dropped connection on reset\0" |
/* 103: 2342, 33 */ "Software caused connection abort\0" |
/* 104: 2375, 25 */ "Connection reset by peer\0" |
/* 105: 2400, 26 */ "No buffer space available\0" |
/* 106: 2426, 40 */ "Transport endpoint is already connected\0" |
/* 107: 2466, 36 */ "Transport endpoint is not connected\0" |
/* 108: 2502, 46 */ "Cannot send after transport endpoint shutdown\0" |
/* 109: 2548, 35 */ "Too many references: cannot splice\0" |
/* 110: 2583, 21 */ "Connection timed out\0" |
/* 111: 2604, 19 */ "Connection refused\0" |
/* 112: 2623, 13 */ "Host is down\0" |
/* 113: 2636, 17 */ "No route to host\0" |
/* 114: 2653, 30 */ "Operation already in progress\0" |
/* 115: 2683, 26 */ "Operation now in progress\0" |
/* 116: 2709, 22 */ "Stale NFS file handle\0" |
/* 117: 2731, 25 */ "Structure needs cleaning\0" |
/* 118: 2756, 28 */ "Not a XENIX named type file\0" |
/* 119: 2784, 30 */ "No XENIX semaphores available\0" |
/* 120: 2814, 21 */ "Is a named type file\0" |
/* 121: 2835, 17 */ "Remote I/O error\0" |
/* 122: 2852, 20 */ "Disk quota exceeded\0" |
/* 123: 2872, 16 */ "No medium found\0" |
/* 124: 2888, 18 */ "Wrong medium type" |
#if defined(__mips__) || defined(__sparc__) |
"\0" |
/* 125: 2906, 28 */ "File locking deadlock error" |
#endif |
/* Note: for mips we are ignoring ECANCELED since glibc doesn't have a |
* corresponsding message.*/ |
}; |
|
#endif |
/**********************************************************************/ |
#if defined(L_sys_errlist) && defined(__UCLIBC_HAS_SYS_ERRLIST__) |
|
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.") |
|
const char *const sys_errlist[] = { |
[0] = _string_syserrmsgs + 0, |
[EPERM] = _string_syserrmsgs + 8, |
[ENOENT] = _string_syserrmsgs + 32, |
[ESRCH] = _string_syserrmsgs + 58, |
[EINTR] = _string_syserrmsgs + 74, |
[EIO] = _string_syserrmsgs + 98, |
[ENXIO] = _string_syserrmsgs + 117, |
[E2BIG] = _string_syserrmsgs + 143, |
[ENOEXEC] = _string_syserrmsgs + 166, |
[EBADF] = _string_syserrmsgs + 184, |
[ECHILD] = _string_syserrmsgs + 204, |
[EAGAIN] = _string_syserrmsgs + 223, |
[ENOMEM] = _string_syserrmsgs + 256, |
[EACCES] = _string_syserrmsgs + 279, |
[EFAULT] = _string_syserrmsgs + 297, |
[ENOTBLK] = _string_syserrmsgs + 309, |
[EBUSY] = _string_syserrmsgs + 331, |
[EEXIST] = _string_syserrmsgs + 355, |
[EXDEV] = _string_syserrmsgs + 367, |
[ENODEV] = _string_syserrmsgs + 393, |
[ENOTDIR] = _string_syserrmsgs + 408, |
[EISDIR] = _string_syserrmsgs + 424, |
[EINVAL] = _string_syserrmsgs + 439, |
[ENFILE] = _string_syserrmsgs + 456, |
[EMFILE] = _string_syserrmsgs + 486, |
[ENOTTY] = _string_syserrmsgs + 506, |
[ETXTBSY] = _string_syserrmsgs + 537, |
[EFBIG] = _string_syserrmsgs + 552, |
[ENOSPC] = _string_syserrmsgs + 567, |
[ESPIPE] = _string_syserrmsgs + 591, |
[EROFS] = _string_syserrmsgs + 604, |
[EMLINK] = _string_syserrmsgs + 626, |
[EPIPE] = _string_syserrmsgs + 641, |
[EDOM] = _string_syserrmsgs + 653, |
[ERANGE] = _string_syserrmsgs + 686, |
[EDEADLK] = _string_syserrmsgs + 716, |
[ENAMETOOLONG] = _string_syserrmsgs + 742, |
[ENOLCK] = _string_syserrmsgs + 761, |
[ENOSYS] = _string_syserrmsgs + 780, |
[ENOTEMPTY] = _string_syserrmsgs + 805, |
[ELOOP] = _string_syserrmsgs + 825, |
/* _string_syserrmsgs + 859, */ |
[ENOMSG] = _string_syserrmsgs + 860, |
[EIDRM] = _string_syserrmsgs + 887, |
[ECHRNG] = _string_syserrmsgs + 906, |
[EL2NSYNC] = _string_syserrmsgs + 934, |
[EL3HLT] = _string_syserrmsgs + 959, |
[EL3RST] = _string_syserrmsgs + 974, |
[ELNRNG] = _string_syserrmsgs + 988, |
[EUNATCH] = _string_syserrmsgs + 1013, |
[ENOCSI] = _string_syserrmsgs + 1042, |
[EL2HLT] = _string_syserrmsgs + 1069, |
[EBADE] = _string_syserrmsgs + 1084, |
[EBADR] = _string_syserrmsgs + 1101, |
[EXFULL] = _string_syserrmsgs + 1128, |
[ENOANO] = _string_syserrmsgs + 1142, |
[EBADRQC] = _string_syserrmsgs + 1151, |
[EBADSLT] = _string_syserrmsgs + 1172, |
/* _string_syserrmsgs + 1185, */ |
[EBFONT] = _string_syserrmsgs + 1186, |
[ENOSTR] = _string_syserrmsgs + 1207, |
[ENODATA] = _string_syserrmsgs + 1227, |
[ETIME] = _string_syserrmsgs + 1245, |
[ENOSR] = _string_syserrmsgs + 1259, |
[ENONET] = _string_syserrmsgs + 1284, |
[ENOPKG] = _string_syserrmsgs + 1314, |
[EREMOTE] = _string_syserrmsgs + 1336, |
[ENOLINK] = _string_syserrmsgs + 1353, |
[EADV] = _string_syserrmsgs + 1375, |
[ESRMNT] = _string_syserrmsgs + 1391, |
[ECOMM] = _string_syserrmsgs + 1405, |
[EPROTO] = _string_syserrmsgs + 1433, |
[EMULTIHOP] = _string_syserrmsgs + 1448, |
[EDOTDOT] = _string_syserrmsgs + 1467, |
[EBADMSG] = _string_syserrmsgs + 1486, |
[EOVERFLOW] = _string_syserrmsgs + 1498, |
[ENOTUNIQ] = _string_syserrmsgs + 1536, |
[EBADFD] = _string_syserrmsgs + 1563, |
[EREMCHG] = _string_syserrmsgs + 1592, |
[ELIBACC] = _string_syserrmsgs + 1615, |
[ELIBBAD] = _string_syserrmsgs + 1654, |
[ELIBSCN] = _string_syserrmsgs + 1691, |
[ELIBMAX] = _string_syserrmsgs + 1723, |
[ELIBEXEC] = _string_syserrmsgs + 1771, |
[EILSEQ] = _string_syserrmsgs + 1809, |
[ERESTART] = _string_syserrmsgs + 1859, |
[ESTRPIPE] = _string_syserrmsgs + 1903, |
[EUSERS] = _string_syserrmsgs + 1922, |
[ENOTSOCK] = _string_syserrmsgs + 1937, |
[EDESTADDRREQ] = _string_syserrmsgs + 1968, |
[EMSGSIZE] = _string_syserrmsgs + 1997, |
[EPROTOTYPE] = _string_syserrmsgs + 2014, |
[ENOPROTOOPT] = _string_syserrmsgs + 2045, |
[EPROTONOSUPPORT] = _string_syserrmsgs + 2068, |
[ESOCKTNOSUPPORT] = _string_syserrmsgs + 2091, |
[EOPNOTSUPP] = _string_syserrmsgs + 2117, |
[EPFNOSUPPORT] = _string_syserrmsgs + 2141, |
[EAFNOSUPPORT] = _string_syserrmsgs + 2171, |
[EADDRINUSE] = _string_syserrmsgs + 2212, |
[EADDRNOTAVAIL] = _string_syserrmsgs + 2235, |
[ENETDOWN] = _string_syserrmsgs + 2267, |
[ENETUNREACH] = _string_syserrmsgs + 2283, |
[ENETRESET] = _string_syserrmsgs + 2306, |
[ECONNABORTED] = _string_syserrmsgs + 2342, |
[ECONNRESET] = _string_syserrmsgs + 2375, |
[ENOBUFS] = _string_syserrmsgs + 2400, |
[EISCONN] = _string_syserrmsgs + 2426, |
[ENOTCONN] = _string_syserrmsgs + 2466, |
[ESHUTDOWN] = _string_syserrmsgs + 2502, |
[ETOOMANYREFS] = _string_syserrmsgs + 2548, |
[ETIMEDOUT] = _string_syserrmsgs + 2583, |
[ECONNREFUSED] = _string_syserrmsgs + 2604, |
[EHOSTDOWN] = _string_syserrmsgs + 2623, |
[EHOSTUNREACH] = _string_syserrmsgs + 2636, |
[EALREADY] = _string_syserrmsgs + 2653, |
[EINPROGRESS] = _string_syserrmsgs + 2683, |
[ESTALE] = _string_syserrmsgs + 2709, |
[EUCLEAN] = _string_syserrmsgs + 2731, |
[ENOTNAM] = _string_syserrmsgs + 2756, |
[ENAVAIL] = _string_syserrmsgs + 2784, |
[EISNAM] = _string_syserrmsgs + 2814, |
[EREMOTEIO] = _string_syserrmsgs + 2835, |
[EDQUOT] = _string_syserrmsgs + 2852, |
[ENOMEDIUM] = _string_syserrmsgs + 2872, |
[EMEDIUMTYPE] = _string_syserrmsgs + 2888, |
|
#if EDEADLOCK != EDEADLK |
[EDEADLOCK] = _string_syserrmsgs + 2906, |
#endif |
|
#if EWOULDBLOCK != EAGAIN |
#error EWOULDBLOCK does not equal EAGAIN |
#endif |
|
/* For now, ignore the other arch-specific errors. glibc only maps EPROCLIM. */ |
|
/* some other mips errors */ |
#ifdef ECANCELED |
#endif |
#ifdef EINIT |
#endif |
#ifdef EREMDEV |
#endif |
|
/* some other sparc errors */ |
#ifdef EPROCLIM |
#endif |
#ifdef ERREMOTE |
#endif |
}; |
|
int sys_nerr = sizeof(sys_errlist)/sizeof(sys_errlist[0]); |
|
#endif |
/**********************************************************************/ |
#ifdef L_wmemcpy |
#define L_memcpy |
#define Wmemcpy wmemcpy |
#else |
#define Wmemcpy memcpy |
#endif |
|
#ifdef L_memcpy |
|
Wvoid *Wmemcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n) |
{ |
register Wchar *r1 = s1; |
register const Wchar *r2 = s2; |
|
#ifdef __BCC__ |
while (n--) { |
*r1++ = *r2++; |
} |
#else |
while (n) { |
*r1++ = *r2++; |
--n; |
} |
#endif |
|
return s1; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wmemmove |
#define L_memmove |
#define Wmemmove wmemmove |
#else |
#define Wmemmove memmove |
#endif |
|
#ifdef L_memmove |
|
Wvoid *Wmemmove(Wvoid *s1, const Wvoid *s2, size_t n) |
{ |
#ifdef __BCC__ |
register Wchar *s = (Wchar *) s1; |
register const Wchar *p = (const Wchar *) s2; |
|
if (p >= s) { |
while (n--) { |
*s++ = *p++; |
} |
} else { |
s += n; |
p += n; |
while (n--) { |
*--s = *--p; |
} |
} |
|
return s1; |
#else |
register Wchar *s = (Wchar *) s1; |
register const Wchar *p = (const Wchar *) s2; |
|
if (p >= s) { |
while (n) { |
*s++ = *p++; |
--n; |
} |
} else { |
while (n) { |
--n; |
s[n] = p[n]; |
} |
} |
|
return s1; |
#endif |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcscpy |
#define L_strcpy |
#define Wstrcpy wcscpy |
#else |
#define Wstrcpy strcpy |
#endif |
|
#ifdef L_strcpy |
|
Wchar *Wstrcpy(Wchar * __restrict s1, const Wchar * __restrict s2) |
{ |
register Wchar *s = s1; |
|
#ifdef __BCC__ |
do { |
*s = *s2++; |
} while (*s++ != 0); |
#else |
while ( (*s++ = *s2++) != 0 ); |
#endif |
|
return s1; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcsncpy |
#define L_strncpy |
#define Wstrncpy wcsncpy |
#else |
#define Wstrncpy strncpy |
#endif |
|
#ifdef L_strncpy |
|
Wchar *Wstrncpy(Wchar * __restrict s1, register const Wchar * __restrict s2, |
size_t n) |
{ |
register Wchar *s = s1; |
|
#ifdef __BCC__ |
while (n--) { |
if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */ |
++s; |
} |
#else |
while (n) { |
if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */ |
++s; |
--n; |
} |
#endif |
|
return s1; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcscat |
#define L_strcat |
#define Wstrcat wcscat |
#else |
#define Wstrcat strcat |
#endif |
|
#ifdef L_strcat |
|
Wchar *Wstrcat(Wchar * __restrict s1, register const Wchar * __restrict s2) |
{ |
register Wchar *s = s1; |
|
while (*s++); |
--s; |
while ((*s++ = *s2++) != 0); |
|
return s1; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcsncat |
#define L_strncat |
#define Wstrncat wcsncat |
#else |
#define Wstrncat strncat |
#endif |
|
#ifdef L_strncat |
|
Wchar *Wstrncat(Wchar * __restrict s1, register const Wchar * __restrict s2, |
size_t n) |
{ |
register Wchar *s = s1; |
|
while (*s++); |
--s; |
#if __BCC__ |
while (n-- && ((*s = *s2++) != 0)) ++s; |
#else |
while (n && ((*s = *s2++) != 0)) { |
--n; |
++s; |
} |
#endif |
*s = 0; |
|
return s1; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wmemcmp |
#define L_memcmp |
#define Wmemcmp wmemcmp |
#else |
#define Wmemcmp memcmp |
#endif |
|
#ifdef L_memcmp |
|
#ifndef L_wmemcmp |
weak_alias(memcmp,bcmp); |
#endif |
|
int Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n) |
{ |
register const Wuchar *r1 = (const Wuchar *) s1; |
register const Wuchar *r2 = (const Wuchar *) s2; |
|
#ifdef WANT_WIDE |
while (n && (*r1 == *r2)) { |
++r1; |
++r2; |
--n; |
} |
|
return (n == 0) ? 0 : ((*r1 < *r2) ? -1 : 1); |
#else |
int r = 0; |
|
while (n-- && ((r = ((int)(*r1++)) - *r2++) == 0)); |
|
return r; |
#endif |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcscmp |
#define L_strcmp |
#define Wstrcmp wcscmp |
#else |
#define Wstrcmp strcmp |
#endif |
|
#ifdef L_strcmp |
|
#ifdef __LOCALE_C_ONLY |
#ifdef L_wcscmp |
weak_alias(wcscmp,wcscoll); |
#else /* L_wcscmp */ |
weak_alias(strcmp,strcoll); |
#endif /* L_wcscmp */ |
#endif /* __LOCALE_C_ONLY */ |
|
int Wstrcmp(register const Wchar *s1, register const Wchar *s2) |
{ |
#ifdef WANT_WIDE |
while (*((Wuchar *)s1) == *((Wuchar *)s2)) { |
if (!*s1++) { |
return 0; |
} |
++s2; |
} |
|
return (*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1; |
#else |
int r; |
|
while (((r = ((int)(*((Wuchar *)s1))) - *((Wuchar *)s2++)) |
== 0) && *s1++); |
|
return r; |
#endif |
} |
#endif |
/**********************************************************************/ |
#ifdef L_wcsncmp |
#define L_strncmp |
#define Wstrncmp wcsncmp |
#else |
#define Wstrncmp strncmp |
#endif |
|
#ifdef L_strncmp |
|
int Wstrncmp(register const Wchar *s1, register const Wchar *s2, size_t n) |
{ |
#ifdef WANT_WIDE |
while (n && (*((Wuchar *)s1) == *((Wuchar *)s2))) { |
if (!*s1++) { |
return 0; |
} |
++s2; |
--n; |
} |
|
return (n == 0) ? 0 : ((*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1); |
#else |
int r = 0; |
|
while (n-- |
&& ((r = ((int)(*((unsigned char *)s1))) - *((unsigned char *)s2++)) |
== 0) |
&& *s1++); |
|
return r; |
#endif |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wmemchr |
#define L_memchr |
#define Wmemchr wmemchr |
#else |
#define Wmemchr memchr |
#endif |
|
#ifdef L_memchr |
|
Wvoid *Wmemchr(const Wvoid *s, Wint c, size_t n) |
{ |
register const Wuchar *r = (const Wuchar *) s; |
#ifdef __BCC__ |
/* bcc can optimize the counter if it thinks it is a pointer... */ |
register const char *np = (const char *) n; |
#else |
#define np n |
#endif |
|
while (np) { |
if (*r == ((Wuchar)c)) { |
return (Wvoid *) r; /* silence the warning */ |
} |
++r; |
--np; |
} |
|
return NULL; |
} |
#undef np |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcschr |
#define L_strchr |
#define Wstrchr wcschr |
#else |
#define Wstrchr strchr |
#endif |
|
#ifdef L_strchr |
|
#ifndef L_wcschr |
weak_alias(strchr,index); |
#endif |
|
Wchar *Wstrchr(register const Wchar *s, Wint c) |
{ |
do { |
if (*s == ((Wchar)c)) { |
return (Wchar *) s; /* silence the warning */ |
} |
} while (*s++); |
|
return NULL; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcscspn |
#define L_strcspn |
#define Wstrcspn wcscspn |
#else |
#define Wstrcspn strcspn |
#endif |
|
#ifdef L_strcspn |
|
size_t Wstrcspn(const Wchar *s1, const Wchar *s2) |
{ |
register const Wchar *s; |
register const Wchar *p; |
|
for ( s=s1 ; *s ; s++ ) { |
for ( p=s2 ; *p ; p++ ) { |
if (*p == *s) goto done; |
} |
} |
done: |
return s - s1; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcspbrk |
#define L_strpbrk |
#define Wstrpbrk wcspbrk |
#else |
#define Wstrpbrk strpbrk |
#endif |
|
#ifdef L_strpbrk |
|
Wchar *Wstrpbrk(const Wchar *s1, const Wchar *s2) |
{ |
register const Wchar *s; |
register const Wchar *p; |
|
for ( s=s1 ; *s ; s++ ) { |
for ( p=s2 ; *p ; p++ ) { |
if (*p == *s) return (Wchar *) s; /* silence the warning */ |
} |
} |
return NULL; |
} |
#endif |
/**********************************************************************/ |
#ifdef L_wcsrchr |
#define L_strrchr |
#define Wstrrchr wcsrchr |
#else |
#define Wstrrchr strrchr |
#endif |
|
#ifdef L_strrchr |
|
#ifndef L_wcsrchr |
weak_alias(strrchr,rindex); |
#endif |
|
Wchar *Wstrrchr(register const Wchar *s, Wint c) |
{ |
register const Wchar *p; |
|
p = NULL; |
do { |
if (*s == (Wchar) c) { |
p = s; |
} |
} while (*s++); |
|
return (Wchar *) p; /* silence the warning */ |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcsspn |
#define L_strspn |
#define Wstrspn wcsspn |
#else |
#define Wstrspn strspn |
#endif |
|
#ifdef L_strspn |
|
size_t Wstrspn(const Wchar *s1, const Wchar *s2) |
{ |
register const Wchar *s = s1; |
register const Wchar *p = s2; |
|
while (*p) { |
if (*p++ == *s) { |
++s; |
p = s2; |
} |
} |
return s - s1; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcsstr |
#define L_strstr |
#define Wstrstr wcsstr |
#else |
#define Wstrstr strstr |
#endif |
|
#ifdef L_strstr |
|
/* NOTE: This is the simple-minded O(len(s1) * len(s2)) worst-case approach. */ |
|
#ifdef L_wcsstr |
weak_alias(wcsstr,wcswcs); |
#endif |
|
Wchar *Wstrstr(const Wchar *s1, const Wchar *s2) |
{ |
register const Wchar *s = s1; |
register const Wchar *p = s2; |
|
do { |
if (!*p) { |
return (Wchar *) s1;; |
} |
if (*p == *s) { |
++p; |
++s; |
} else { |
p = s2; |
if (!*s) { |
return NULL; |
} |
s = ++s1; |
} |
} while (1); |
} |
|
#endif |
/**********************************************************************/ |
#undef Wstrspn |
#undef Wstrpbrk |
|
#ifdef L_wcstok |
#define L_strtok_r |
#define Wstrtok_r wcstok |
#define Wstrspn wcsspn |
#define Wstrpbrk wcspbrk |
#else |
#define Wstrtok_r strtok_r |
#define Wstrspn strspn |
#define Wstrpbrk strpbrk |
#endif |
|
#ifdef L_strtok_r |
|
Wchar *Wstrtok_r(Wchar * __restrict s1, const Wchar * __restrict s2, |
Wchar ** __restrict next_start) |
{ |
register Wchar *s; |
register Wchar *p; |
|
#if 1 |
if (((s = s1) != NULL) || ((s = *next_start) != NULL)) { |
if (*(s += Wstrspn(s, s2))) { |
if ((p = Wstrpbrk(s, s2)) != NULL) { |
*p++ = 0; |
} |
} else { |
p = s = NULL; |
} |
*next_start = p; |
} |
return s; |
#else |
if (!(s = s1)) { |
s = *next_start; |
} |
if (s && *(s += Wstrspn(s, s2))) { |
if (*(p = s + Wstrcspn(s, s2))) { |
*p++ = 0; |
} |
*next_start = p; |
return s; |
} |
return NULL; /* TODO: set *next_start = NULL for safety? */ |
#endif |
} |
|
#endif |
/**********************************************************************/ |
/* #ifdef L_wcstok */ |
/* #define L_strtok */ |
/* #define Wstrtok wcstok */ |
/* #define Wstrtok_r wcstok_r */ |
/* #else */ |
/* #define Wstrtok strtok */ |
/* #define Wstrtok_r strtok_r */ |
/* #endif */ |
|
#ifdef L_strtok |
#define Wstrtok strtok |
#define Wstrtok_r strtok_r |
|
Wchar *Wstrtok(Wchar * __restrict s1, const Wchar * __restrict s2) |
{ |
static Wchar *next_start; /* Initialized to 0 since in bss. */ |
return Wstrtok_r(s1, s2, &next_start); |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wmemset |
#define L_memset |
#define Wmemset wmemset |
#else |
#define Wmemset memset |
#endif |
|
#ifdef L_memset |
|
Wvoid *Wmemset(Wvoid *s, Wint c, size_t n) |
{ |
register Wuchar *p = (Wuchar *) s; |
#ifdef __BCC__ |
/* bcc can optimize the counter if it thinks it is a pointer... */ |
register const char *np = (const char *) n; |
#else |
#define np n |
#endif |
|
while (np) { |
*p++ = (Wuchar) c; |
--np; |
} |
|
return s; |
} |
#undef np |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcslen |
#define L_strlen |
#define Wstrlen wcslen |
#else |
#define Wstrlen strlen |
#endif |
|
#ifdef L_strlen |
|
size_t Wstrlen(const Wchar *s) |
{ |
register const Wchar *p; |
|
for (p=s ; *p ; p++); |
|
return p - s; |
} |
|
#endif |
/**********************************************************************/ |
/* ANSI/ISO end here */ |
/**********************************************************************/ |
#ifdef L_ffs |
|
int ffs(int i) |
{ |
#if 1 |
/* inlined binary search method */ |
char n = 1; |
#if UINT_MAX == 0xffffU |
/* nothing to do here -- just trying to avoiding possible problems */ |
#elif UINT_MAX == 0xffffffffU |
if (!(i & 0xffff)) { |
n += 16; |
i >>= 16; |
} |
#else |
#error ffs needs rewriting! |
#endif |
|
if (!(i & 0xff)) { |
n += 8; |
i >>= 8; |
} |
if (!(i & 0x0f)) { |
n += 4; |
i >>= 4; |
} |
if (!(i & 0x03)) { |
n += 2; |
i >>= 2; |
} |
return (i) ? (n + ((i+1) & 0x01)) : 0; |
|
#else |
/* linear search -- slow, but small */ |
int n; |
|
for (n = 0 ; i ; ++n) { |
i >>= 1; |
} |
|
return n; |
#endif |
} |
|
#endif |
/**********************************************************************/ |
#if defined(L_strcasecmp) || defined(L_strcasecmp_l) || defined(L_wcscasecmp) || defined(L_wcscasecmp_l) |
|
#if defined(L_wcscasecmp) || defined(L_wcscasecmp_l) |
|
#define strcasecmp wcscasecmp |
#define strcasecmp_l wcscasecmp_l |
#define __strcasecmp_l __wcscasecmp_l |
#ifdef __UCLIBC_DO_XLOCALE |
#define TOLOWER(C) __towlower_l((C), locale_arg) |
#else |
#define TOLOWER(C) towlower((C)) |
#endif |
|
#else /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */ |
|
#ifdef __UCLIBC_DO_XLOCALE |
#define TOLOWER(C) __tolower_l((C), locale_arg) |
#else |
#define TOLOWER(C) tolower((C)) |
#endif |
|
#endif /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */ |
|
|
#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) |
|
int strcasecmp(register const Wchar *s1, register const Wchar *s2) |
{ |
return __strcasecmp_l(s1, s2, __UCLIBC_CURLOCALE); |
} |
|
#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ |
|
int __XL(strcasecmp)(register const Wchar *s1, register const Wchar *s2 |
__LOCALE_PARAM ) |
{ |
#ifdef WANT_WIDE |
while ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2))) { |
if (!*s1++) { |
return 0; |
} |
++s2; |
} |
|
return (((Wuchar)TOLOWER(*s1)) < ((Wuchar)TOLOWER(*s2))) ? -1 : 1; |
/* TODO -- should wide cmp funcs do wchar or Wuchar compares? */ |
#else |
int r = 0; |
|
while ( ((s1 == s2) || |
!(r = ((int)( TOLOWER(*((Wuchar *)s1)))) |
- TOLOWER(*((Wuchar *)s2)))) |
&& (++s2, *s1++)); |
|
return r; |
#endif |
} |
|
__XL_ALIAS(strcasecmp) |
|
#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ |
|
#endif |
/**********************************************************************/ |
#if defined(L_strncasecmp) || defined(L_strncasecmp_l) || defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) |
|
#if defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) |
|
#define strncasecmp wcsncasecmp |
#define strncasecmp_l wcsncasecmp_l |
#define __strncasecmp_l __wcsncasecmp_l |
#ifdef __UCLIBC_DO_XLOCALE |
#define TOLOWER(C) __towlower_l((C), locale_arg) |
#else |
#define TOLOWER(C) towlower((C)) |
#endif |
|
#else /* defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) */ |
|
#ifdef __UCLIBC_DO_XLOCALE |
#define TOLOWER(C) __tolower_l((C), locale_arg) |
#else |
#define TOLOWER(C) tolower((C)) |
#endif |
|
#endif /* defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) */ |
|
|
#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) |
|
int strncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n) |
{ |
return __strncasecmp_l(s1, s2, n, __UCLIBC_CURLOCALE); |
} |
|
#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ |
|
int __XL(strncasecmp)(register const Wchar *s1, register const Wchar *s2, |
size_t n __LOCALE_PARAM ) |
{ |
#ifdef WANT_WIDE |
while (n && ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2)))) { |
if (!*s1++) { |
return 0; |
} |
++s2; |
--n; |
} |
|
return (n == 0) |
? 0 |
: ((((Wuchar)TOLOWER(*s1)) < ((Wuchar)TOLOWER(*s2))) ? -1 : 1); |
/* TODO -- should wide cmp funcs do wchar or Wuchar compares? */ |
#else |
int r = 0; |
|
while ( n |
&& ((s1 == s2) || |
!(r = ((int)( TOLOWER(*((unsigned char *)s1)))) |
- TOLOWER(*((unsigned char *)s2)))) |
&& (--n, ++s2, *s1++)); |
return r; |
#endif |
} |
|
__XL_ALIAS(strncasecmp) |
|
#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcsnlen |
#define L_strnlen |
#define Wstrnlen wcsnlen |
#else |
#define Wstrnlen strnlen |
#endif |
|
#ifdef L_strnlen |
|
size_t Wstrnlen(const Wchar *s, size_t max) |
{ |
register const Wchar *p = s; |
#ifdef __BCC__ |
/* bcc can optimize the counter if it thinks it is a pointer... */ |
register const char *maxp = (const char *) max; |
#else |
#define maxp max |
#endif |
|
while (maxp && *p) { |
++p; |
--maxp; |
} |
|
return p - s; |
} |
#undef maxp |
#endif |
/**********************************************************************/ |
/* No wide analog. */ |
|
#ifdef L_memccpy |
|
void *memccpy(void * __restrict s1, const void * __restrict s2, int c, size_t n) |
{ |
register char *r1 = s1; |
register const char *r2 = s2; |
|
while (n-- && (((unsigned char)(*r1++ = *r2++)) != ((unsigned char) c))); |
|
return (n == (size_t) -1) ? NULL : r1; |
} |
|
#endif |
/**********************************************************************/ |
#undef Wstrlen |
#undef Wstrcpy |
|
#ifdef L_wcsdup |
#define L_strdup |
#define Wstrdup wcsdup |
#define Wstrlen wcslen |
#define Wstrcpy wcscpy |
#else |
#define Wstrdup strdup |
#define Wstrlen strlen |
#define Wstrcpy strcpy |
#endif |
|
#ifdef L_strdup |
|
Wchar *Wstrdup(register const Wchar *s1) |
{ |
register Wchar *s; |
|
if ((s = malloc((Wstrlen(s1) + 1) * sizeof(Wchar))) != NULL) { |
Wstrcpy(s, s1); |
} |
|
return s; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_strerror |
|
char *strerror(int errnum) |
{ |
static char buf[_STRERROR_BUFSIZE]; |
|
_susv3_strerror_r(errnum, buf, sizeof(buf)); |
|
return buf; |
} |
|
#endif |
/**********************************************************************/ |
/* SUSv3 functions. */ |
/**********************************************************************/ |
#ifdef L__susv3_strerror_r |
|
#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__ |
#if defined(__alpha__) || defined(__mips__) || defined(__sparc__) |
|
static const unsigned char estridx[] = { |
0, /* success is always 0 */ |
EPERM, |
ENOENT, |
ESRCH, |
EINTR, |
EIO, |
ENXIO, |
E2BIG, |
ENOEXEC, |
EBADF, |
ECHILD, |
EAGAIN, |
ENOMEM, |
EACCES, |
EFAULT, |
ENOTBLK, |
EBUSY, |
EEXIST, |
EXDEV, |
ENODEV, |
ENOTDIR, |
EISDIR, |
EINVAL, |
ENFILE, |
EMFILE, |
ENOTTY, |
ETXTBSY, |
EFBIG, |
ENOSPC, |
ESPIPE, |
EROFS, |
EMLINK, |
EPIPE, |
EDOM, |
ERANGE, |
EDEADLK, |
ENAMETOOLONG, |
ENOLCK, |
ENOSYS, |
ENOTEMPTY, |
ELOOP, |
0, |
ENOMSG, |
EIDRM, |
ECHRNG, |
EL2NSYNC, |
EL3HLT, |
EL3RST, |
ELNRNG, |
EUNATCH, |
ENOCSI, |
EL2HLT, |
EBADE, |
EBADR, |
EXFULL, |
ENOANO, |
EBADRQC, |
EBADSLT, |
0, |
EBFONT, |
ENOSTR, |
ENODATA, |
ETIME, |
ENOSR, |
ENONET, |
ENOPKG, |
EREMOTE, |
ENOLINK, |
EADV, |
ESRMNT, |
ECOMM, |
EPROTO, |
EMULTIHOP, |
EDOTDOT, |
EBADMSG, |
EOVERFLOW, |
ENOTUNIQ, |
EBADFD, |
EREMCHG, |
ELIBACC, |
ELIBBAD, |
ELIBSCN, |
ELIBMAX, |
ELIBEXEC, |
EILSEQ, |
ERESTART, |
ESTRPIPE, |
EUSERS, |
ENOTSOCK, |
EDESTADDRREQ, |
EMSGSIZE, |
EPROTOTYPE, |
ENOPROTOOPT, |
EPROTONOSUPPORT, |
ESOCKTNOSUPPORT, |
EOPNOTSUPP, |
EPFNOSUPPORT, |
EAFNOSUPPORT, |
EADDRINUSE, |
EADDRNOTAVAIL, |
ENETDOWN, |
ENETUNREACH, |
ENETRESET, |
ECONNABORTED, |
ECONNRESET, |
ENOBUFS, |
EISCONN, |
ENOTCONN, |
ESHUTDOWN, |
ETOOMANYREFS, |
ETIMEDOUT, |
ECONNREFUSED, |
EHOSTDOWN, |
EHOSTUNREACH, |
EALREADY, |
EINPROGRESS, |
ESTALE, |
EUCLEAN, |
ENOTNAM, |
ENAVAIL, |
EISNAM, |
EREMOTEIO, |
#ifdef __mips__ |
0, /* mips has an outrageous value for this... */ |
#else |
EDQUOT, |
#endif |
ENOMEDIUM, |
EMEDIUMTYPE, |
#if defined(__mips__) || defined(__sparc__) |
EDEADLOCK, |
#endif |
}; |
|
#endif |
|
int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen) |
{ |
register char *s; |
int i, retval; |
char buf[_STRERROR_BUFSIZE]; |
static const char unknown[] = { |
'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' ' |
}; |
|
retval = EINVAL; |
|
|
#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__ |
|
#if defined(__alpha__) || defined(__mips__) || defined(__sparc__) |
/* Need to translate errno to string index. */ |
for (i = 0 ; i < sizeof(estridx)/sizeof(estridx[0]) ; i++) { |
if (estridx[i] == errnum) { |
goto GOT_ESTRIDX; |
} |
} |
i = INT_MAX; /* Failed, but may need to check mips special case. */ |
#ifdef __mips__ |
if (errnum == EDQUOT) { /* Deal with large EDQUOT value on mips */ |
i = 122; |
} |
#endif /* __mips__ */ |
GOT_ESTRIDX: |
#else |
/* No errno to string index translation needed. */ |
i = errnum; |
#endif |
|
if (((unsigned int) i) < _SYS_NERR) { |
/* Trade time for space. This function should rarely be called |
* so rather than keeping an array of pointers for the different |
* messages, just run through the buffer until we find the |
* correct string. */ |
for (s = (char *) _string_syserrmsgs ; i ; ++s) { |
if (!*s) { |
--i; |
} |
} |
if (*s) { /* Make sure we have an actual message. */ |
retval = 0; |
goto GOT_MESG; |
} |
} |
|
#endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */ |
|
s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown); |
memcpy(s, unknown, sizeof(unknown)); |
|
GOT_MESG: |
if (!strerrbuf) { /* SUSv3 */ |
buflen = 0; |
} |
i = strlen(s) + 1; |
if (i > buflen) { |
i = buflen; |
retval = ERANGE; |
} |
|
if (i) { |
memcpy(strerrbuf, s, i); |
strerrbuf[i-1] = 0; /* In case buf was too small. */ |
} |
|
if (retval) { |
__set_errno(retval); |
} |
|
return retval; |
} |
|
#else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */ |
|
int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen) |
{ |
register char *s; |
int i, retval; |
char buf[_STRERROR_BUFSIZE]; |
static const char unknown[] = { |
'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' ' |
}; |
|
s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown); |
memcpy(s, unknown, sizeof(unknown)); |
|
if (!strerrbuf) { /* SUSv3 */ |
buflen = 0; |
} |
|
retval = EINVAL; |
|
i = buf + sizeof(buf) - s; |
|
if (i > buflen) { |
i = buflen; |
retval = ERANGE; |
} |
|
if (i) { |
memcpy(strerrbuf, s, i); |
strerrbuf[i-1] = 0; /* In case buf was too small. */ |
} |
|
__set_errno(retval); |
|
return retval; |
} |
|
#endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */ |
|
#endif |
/**********************************************************************/ |
/* GNU extension functions. */ |
/**********************************************************************/ |
#ifdef L__glibc_strerror_r |
|
weak_alias(_glibc_strerror_r,__strerror_r); |
|
char *_glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen) |
{ |
_susv3_strerror_r(errnum, strerrbuf, buflen); |
|
return strerrbuf; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_memmem |
|
void *memmem(const void *haystack, size_t haystacklen, |
const void *needle, size_t needlelen) |
{ |
register const char *ph; |
register const char *pn; |
const char *plast; |
size_t n; |
|
if (needlelen == 0) { |
return (void *) haystack; |
} |
|
if (haystacklen >= needlelen) { |
ph = (const char *) haystack; |
pn = (const char *) needle; |
plast = ph + (haystacklen - needlelen); |
|
do { |
n = 0; |
while (ph[n] == pn[n]) { |
if (++n == needlelen) { |
return (void *) ph; |
} |
} |
} while (++ph <= plast); |
} |
|
return NULL; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wmempcpy |
#define L_mempcpy |
#define Wmempcpy wmempcpy |
#else |
#define Wmempcpy mempcpy |
#endif |
|
#ifdef L_mempcpy |
|
#ifndef L_wmempcpy |
/* uClibc's old string implementation did this to cater to some app. */ |
weak_alias(mempcpy,__mempcpy); |
#endif |
|
Wvoid *Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n) |
{ |
register Wchar *r1 = s1; |
register const Wchar *r2 = s2; |
|
#ifdef __BCC__ |
while (n--) { |
*r1++ = *r2++; |
} |
#else |
while (n) { |
*r1++ = *r2++; |
--n; |
} |
#endif |
|
return r1; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_memrchr |
|
void *memrchr(const void *s, int c, size_t n) |
{ |
register const unsigned char *r; |
#ifdef __BCC__ |
/* bcc can optimize the counter if it thinks it is a pointer... */ |
register const char *np = (const char *) n; |
#else |
#define np n |
#endif |
|
r = ((unsigned char *)s) + ((size_t) np); |
|
while (np) { |
if (*--r == ((unsigned char)c)) { |
return (void *) r; /* silence the warning */ |
} |
--np; |
} |
|
return NULL; |
} |
#undef np |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcpcpy |
#define L_stpcpy |
#define Wstpcpy wcpcpy |
#else |
#define Wstpcpy stpcpy |
#endif |
|
#ifdef L_stpcpy |
|
Wchar *Wstpcpy(register Wchar * __restrict s1, const Wchar * __restrict s2) |
{ |
#ifdef __BCC__ |
do { |
*s1 = *s2++; |
} while (*s1++ != 0); |
#else |
while ( (*s1++ = *s2++) != 0 ); |
#endif |
|
return s1 - 1; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcpncpy |
#define L_stpncpy |
#define Wstpncpy wcpncpy |
#else |
#define Wstpncpy stpncpy |
#endif |
|
#ifdef L_stpncpy |
|
Wchar *Wstpncpy(register Wchar * __restrict s1, |
register const Wchar * __restrict s2, |
size_t n) |
{ |
Wchar *s = s1; |
const Wchar *p = s2; |
|
#ifdef __BCC__ |
while (n--) { |
if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */ |
++s; |
} |
return s1 + (s2 - p); |
#else |
while (n) { |
if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */ |
++s; |
--n; |
} |
return s1 + (s2 - p); |
#endif |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_bzero |
|
void bzero(void *s, size_t n) |
{ |
register unsigned char *p = s; |
#ifdef __BCC__ |
/* bcc can optimize the counter if it thinks it is a pointer... */ |
register const char *np = (const char *) n; |
#else |
#define np n |
#endif |
|
while (np) { |
*p++ = 0; |
--np; |
} |
} |
#undef np |
|
#endif |
/**********************************************************************/ |
#ifdef L_bcopy |
|
void bcopy(const void *s2, void *s1, size_t n) |
{ |
#if 1 |
memmove(s1, s2, n); |
#else |
#ifdef __BCC__ |
register char *s; |
register const char *p; |
|
s = s1; |
p = s2; |
if (p >= s) { |
while (n--) { |
*s++ = *p++; |
} |
} else { |
s += n; |
p += n; |
while (n--) { |
*--s = *--p; |
} |
} |
#else |
register char *s; |
register const char *p; |
|
s = s1; |
p = s2; |
if (p >= s) { |
while (n) { |
*s++ = *p++; |
--n; |
} |
} else { |
while (n) { |
--n; |
s[n] = p[n]; |
} |
} |
#endif |
#endif |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_strcasestr |
|
char *strcasestr(const char *s1, const char *s2) |
{ |
register const char *s = s1; |
register const char *p = s2; |
|
#if 1 |
do { |
if (!*p) { |
return (char *) s1;; |
} |
if ((*p == *s) |
|| (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s))) |
) { |
++p; |
++s; |
} else { |
p = s2; |
if (!*s) { |
return NULL; |
} |
s = ++s1; |
} |
} while (1); |
#else |
while (*p && *s) { |
if ((*p == *s) |
|| (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s))) |
) { |
++p; |
++s; |
} else { |
p = s2; |
s = ++s1; |
} |
} |
|
return (*p) ? NULL : (char *) s1; |
#endif |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_strndup |
|
char *strndup(register const char *s1, size_t n) |
{ |
register char *s; |
|
n = strnlen(s1,n); /* Avoid problems if s1 not nul-terminated. */ |
|
if ((s = malloc(n + 1)) != NULL) { |
memcpy(s, s1, n); |
s[n] = 0; |
} |
|
return s; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_strsep |
|
char *strsep(char ** __restrict s1, const char * __restrict s2) |
{ |
register char *s = *s1; |
register char *p; |
|
#if 1 |
p = NULL; |
if (s && *s && (p = strpbrk(s, s2))) { |
*p++ = 0; |
} |
#else |
if (s && *s && *(p = s + strcspn(s, s2))) { |
*p++ = 0; |
} else { |
p = NULL; |
} |
#endif |
*s1 = p; |
return s; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_wcschrnul |
#define L_strchrnul |
#define __Wstrchrnul __wcschrnul |
#define Wstrchrnul wcschrnul |
#else |
#define __Wstrchrnul __strchrnul |
#define Wstrchrnul strchrnul |
#endif |
|
#ifdef L_strchrnul |
|
extern Wchar *__Wstrchrnul(register const Wchar *s, Wint c); |
weak_alias(__Wstrchrnul, Wstrchrnul); |
|
Wchar *__Wstrchrnul(register const Wchar *s, Wint c) |
{ |
--s; |
while (*++s && (*s != ((Wchar)c))); |
return (Wchar *) s; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_rawmemchr |
|
void *rawmemchr(const void *s, int c) |
{ |
register const unsigned char *r = s; |
|
while (*r != ((unsigned char)c)) ++r; |
|
return (void *) r; /* silence the warning */ |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_basename |
|
char *basename(const char *path) |
{ |
register const char *s; |
register const char *p; |
|
p = s = path; |
|
while (*s) { |
if (*s++ == '/') { |
p = s; |
} |
} |
|
return (char *) p; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L___xpg_basename |
|
char *__xpg_basename(register char *path) |
{ |
static const char null_or_empty[] = "."; |
char *first; |
register char *last; |
|
first = (char *) null_or_empty; |
|
if (path && *path) { |
first = path; |
last = path - 1; |
|
do { |
if ((*path != '/') && (path > ++last)) { |
last = first = path; |
} |
} while (*++path); |
|
if (*first == '/') { |
last = first; |
} |
last[1] = 0; |
} |
|
return first; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_dirname |
|
char *dirname(char *path) |
{ |
static const char null_or_empty_or_noslash[] = "."; |
register char *s; |
register char *last; |
char *first; |
|
last = s = path; |
|
if (s != NULL) { |
|
LOOP: |
while (*s && (*s != '/')) ++s; |
first = s; |
while (*s == '/') ++s; |
if (*s) { |
last = first; |
goto LOOP; |
} |
|
if (last == path) { |
if (*last != '/') { |
goto DOT; |
} |
if ((*++last == '/') && (last[1] == 0)) { |
++last; |
} |
} |
*last = 0; |
return path; |
} |
DOT: |
return (char *) null_or_empty_or_noslash; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef L_strlcat |
|
/* OpenBSD function: |
* Append at most n-1-strlen(dst) chars from src to dst and nul-terminate dst. |
* Returns strlen(src) + strlen({original} dst), so truncation occurred if the |
* return val is >= n. |
* Note: If dst doesn't contain a nul in the first n chars, strlen(dst) is |
* taken as n. */ |
|
size_t strlcat(register char *__restrict dst, |
register const char *__restrict src, |
size_t n) |
{ |
size_t len; |
char dummy[1]; |
|
len = 0; |
|
while (1) { |
if (len >= n) { |
dst = dummy; |
break; |
} |
if (!*dst) { |
break; |
} |
++dst; |
++len; |
} |
|
while ((*dst = *src) != 0) { |
if (++len < n) { |
++dst; |
} |
++src; |
} |
|
return len; |
} |
|
#endif |
/**********************************************************************/ |
#ifdef WANT_WIDE |
extern size_t __wcslcpy(wchar_t *__restrict dst, |
const wchar_t *__restrict src, |
size_t n); |
#endif |
|
|
#ifdef L___wcslcpy |
#define L_strlcpy |
#define Wstrlcpy __wcslcpy |
#ifdef __LOCALE_C_ONLY |
weak_alias(__wcslcpy,wcsxfrm); |
#endif |
#endif |
|
#ifdef L_strlcpy |
|
#ifndef L___wcslcpy |
#define Wstrlcpy strlcpy |
#ifdef __LOCALE_C_ONLY |
weak_alias(strlcpy,strxfrm); |
#endif |
#endif |
|
/* OpenBSD function: |
* Copy at most n-1 chars from src to dst and nul-terminate dst. |
* Returns strlen(src), so truncation occurred if the return value is >= n. */ |
|
size_t Wstrlcpy(register Wchar *__restrict dst, |
register const Wchar *__restrict src, |
size_t n) |
{ |
const Wchar *src0 = src; |
Wchar dummy[1]; |
|
if (!n) { |
dst = dummy; |
} else { |
--n; |
} |
|
while ((*dst = *src) != 0) { |
if (n) { |
--n; |
++dst; |
} |
++src; |
} |
|
return src - src0; |
} |
|
#endif |
/**********************************************************************/ |
#if defined(L__string_syssigmsgs) && defined(__UCLIBC_HAS_SIGNUM_MESSAGES__) |
|
const char _string_syssigmsgs[] = { |
/* 0: 0, 1 */ "\0" |
/* 1: 1, 7 */ "Hangup\0" |
/* 2: 8, 10 */ "Interrupt\0" |
/* 3: 18, 5 */ "Quit\0" |
/* 4: 23, 20 */ "Illegal instruction\0" |
/* 5: 43, 22 */ "Trace/breakpoint trap\0" |
/* 6: 65, 8 */ "Aborted\0" |
/* 7: 73, 10 */ "Bus error\0" |
/* 8: 83, 25 */ "Floating point exception\0" |
/* 9: 108, 7 */ "Killed\0" |
/* 10: 115, 22 */ "User defined signal 1\0" |
/* 11: 137, 19 */ "Segmentation fault\0" |
/* 12: 156, 22 */ "User defined signal 2\0" |
/* 13: 178, 12 */ "Broken pipe\0" |
/* 14: 190, 12 */ "Alarm clock\0" |
/* 15: 202, 11 */ "Terminated\0" |
/* 16: 213, 12 */ "Stack fault\0" |
/* 17: 225, 13 */ "Child exited\0" |
/* 18: 238, 10 */ "Continued\0" |
/* 19: 248, 17 */ "Stopped (signal)\0" |
/* 20: 265, 8 */ "Stopped\0" |
/* 21: 273, 20 */ "Stopped (tty input)\0" |
/* 22: 293, 21 */ "Stopped (tty output)\0" |
/* 23: 314, 21 */ "Urgent I/O condition\0" |
/* 24: 335, 24 */ "CPU time limit exceeded\0" |
/* 25: 359, 25 */ "File size limit exceeded\0" |
/* 26: 384, 22 */ "Virtual timer expired\0" |
/* 27: 406, 24 */ "Profiling timer expired\0" |
/* 28: 430, 15 */ "Window changed\0" |
/* 29: 445, 13 */ "I/O possible\0" |
/* 30: 458, 14 */ "Power failure\0" |
/* 31: 472, 16 */ "Bad system call" |
#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__) |
/* 32: 488, 9 */ "\0EMT trap" |
#endif |
}; |
|
#endif |
|
/**********************************************************************/ |
#if defined(L_sys_siglist) && defined(__UCLIBC_HAS_SYS_SIGLIST__) |
|
const char *const sys_siglist[_NSIG] = { |
[0] = NULL, |
[SIGHUP] = _string_syssigmsgs + 1, |
[SIGINT] = _string_syssigmsgs + 8, |
[SIGQUIT] = _string_syssigmsgs + 18, |
[SIGILL] = _string_syssigmsgs + 23, |
[SIGTRAP] = _string_syssigmsgs + 43, |
[SIGABRT] = _string_syssigmsgs + 65, |
[SIGBUS] = _string_syssigmsgs + 73, |
[SIGFPE] = _string_syssigmsgs + 83, |
[SIGKILL] = _string_syssigmsgs + 108, |
[SIGUSR1] = _string_syssigmsgs + 115, |
[SIGSEGV] = _string_syssigmsgs + 137, |
[SIGUSR2] = _string_syssigmsgs + 156, |
[SIGPIPE] = _string_syssigmsgs + 178, |
[SIGALRM] = _string_syssigmsgs + 190, |
[SIGTERM] = _string_syssigmsgs + 202, |
#if !(defined(__alpha__) || defined(__mips__) || defined(__sparc__)) |
[SIGSTKFLT] = _string_syssigmsgs + 213, |
#endif |
[SIGCHLD] = _string_syssigmsgs + 225, |
[SIGCONT] = _string_syssigmsgs + 238, |
[SIGSTOP] = _string_syssigmsgs + 248, |
[SIGTSTP] = _string_syssigmsgs + 265, |
[SIGTTIN] = _string_syssigmsgs + 273, |
[SIGTTOU] = _string_syssigmsgs + 293, |
[SIGURG] = _string_syssigmsgs + 314, |
[SIGXCPU] = _string_syssigmsgs + 335, |
[SIGXFSZ] = _string_syssigmsgs + 359, |
[SIGVTALRM] = _string_syssigmsgs + 384, |
[SIGPROF] = _string_syssigmsgs + 406, |
[SIGWINCH] = _string_syssigmsgs + 430, |
[SIGIO] = _string_syssigmsgs + 445, |
[SIGPWR] = _string_syssigmsgs + 458, |
[SIGSYS] = _string_syssigmsgs + 472, |
#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__) |
[SIGEMT] = _string_syssigmsgs + 488, |
#endif |
}; |
|
#endif |
/**********************************************************************/ |
#ifdef L_strsignal |
|
/* TODO: make a threadsafe version? */ |
|
#ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__ |
|
#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__) |
static const unsigned char sstridx[] = { |
0, |
SIGHUP, |
SIGINT, |
SIGQUIT, |
SIGILL, |
SIGTRAP, |
SIGIOT, |
SIGBUS, |
SIGFPE, |
SIGKILL, |
SIGUSR1, |
SIGSEGV, |
SIGUSR2, |
SIGPIPE, |
SIGALRM, |
SIGTERM, |
#if defined(__alpha__) || defined(__mips__) || defined(__sparc__) |
0, |
#else |
SIGSTKFLT, |
#endif |
SIGCHLD, |
SIGCONT, |
SIGSTOP, |
SIGTSTP, |
SIGTTIN, |
SIGTTOU, |
SIGURG, |
SIGXCPU, |
SIGXFSZ, |
SIGVTALRM, |
SIGPROF, |
SIGWINCH, |
SIGIO, |
SIGPWR, |
SIGSYS, |
#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__) |
SIGEMT, |
#endif |
}; |
#endif |
|
char *strsignal(int signum) |
{ |
register char *s; |
int i; |
static char buf[_STRSIGNAL_BUFSIZE]; |
static const char unknown[] = { |
'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' ' |
}; |
|
#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__) |
/* Need to translate signum to string index. */ |
for (i = 0 ; i < sizeof(sstridx)/sizeof(sstridx[0]) ; i++) { |
if (sstridx[i] == signum) { |
goto GOT_SSTRIDX; |
} |
} |
i = INT_MAX; /* Failed. */ |
GOT_SSTRIDX: |
#else |
/* No signum to string index translation needed. */ |
i = signum; |
#endif |
|
if (((unsigned int) signum) < _SYS_NSIG) { |
/* Trade time for space. This function should rarely be called |
* so rather than keeping an array of pointers for the different |
* messages, just run through the buffer until we find the |
* correct string. */ |
for (s = (char *) _string_syssigmsgs ; i ; ++s) { |
if (!*s) { |
--i; |
} |
} |
if (*s) { /* Make sure we have an actual message. */ |
goto DONE; |
} |
} |
|
s = _int10tostr(buf+sizeof(buf)-1, signum) - sizeof(unknown); |
memcpy(s, unknown, sizeof(unknown)); |
|
DONE: |
return s; |
} |
|
#else /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */ |
|
char *strsignal(int signum) |
{ |
static char buf[_STRSIGNAL_BUFSIZE]; |
static const char unknown[] = { |
'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' ' |
}; |
|
return (char *) memcpy(_int10tostr(buf+sizeof(buf)-1, signum) |
- sizeof(unknown), |
unknown, sizeof(unknown)); |
} |
|
#endif /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */ |
|
#endif |
/**********************************************************************/ |
#ifdef L_psignal |
|
/* TODO: make this threadsafe with a reentrant version of strsignal? */ |
|
void psignal(int signum, register const char *message) |
{ |
/* If the program is calling psignal, it's a safe bet that printf and |
* friends are used as well. It is also possible that the calling |
* program could buffer stderr, or reassign it. */ |
|
register const char *sep; |
|
sep = ": "; |
if (!(message && *message)) { /* Caller did not supply a prefix message */ |
message = (sep += 2); /* or passed an empty string. */ |
} |
|
#if 1 |
fprintf(stderr, "%s%s%s\n", message, sep, strsignal(signum)); |
#else |
/* Note: Assumes stderr not closed or buffered. */ |
__STDIO_THREADLOCK(stderr); |
_stdio_fdout(STDERR_FILENO, message, sep, strsignal(signum)); |
__STDIO_THREADUNLOCK(stderr); |
#endif |
} |
|
#endif |
/**********************************************************************/ |
#ifndef __LOCALE_C_ONLY |
#if defined(L_strxfrm) || defined(L_strxfrm_l) || defined(L_wcsxfrm) || defined(L_wcsxfrm_l) |
|
#ifdef L_strxfrm |
#ifndef WANT_WIDE |
#error WANT_WIDE should be defined for L_strxfrm |
#endif |
#ifdef L_wcsxfrm |
#error L_wcsxfrm already defined for L_strxfrm |
#endif |
#endif /* L_strxfrm */ |
|
#if defined(L_strxfrm) || defined(L_strxfrm_l) |
|
#define wcscoll strcoll |
#define wcscoll_l strcoll_l |
#define __wcscoll_l __strcoll_l |
#define wcsxfrm strxfrm |
#define wcsxfrm_l strxfrm_l |
#define __wcsxfrm_l __strxfrm_l |
|
#undef WANT_WIDE |
#undef Wvoid |
#undef Wchar |
#undef Wuchar |
#undef Wint |
|
#define Wchar char |
|
#endif /* defined(L_strxfrm) || defined(L_strxfrm_l) */ |
|
#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) |
|
int wcscoll (const Wchar *s0, const Wchar *s1) |
{ |
return __wcscoll_l(s0, s1, __UCLIBC_CURLOCALE ); |
} |
|
size_t wcsxfrm(Wchar *__restrict ws1, const Wchar *__restrict ws2, size_t n) |
{ |
return __wcsxfrm_l(ws1, ws2, n, __UCLIBC_CURLOCALE ); |
} |
|
#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ |
|
|
#if 0 |
#define CUR_COLLATE (&__UCLIBC_CURLOCALE_DATA.collate) |
#else |
#define CUR_COLLATE (& __LOCALE_PTR->collate) |
#endif |
|
#define MAX_PENDING 8 |
|
typedef struct { |
const Wchar *s; |
const Wchar *eob; /* end of backward */ |
|
__uwchar_t weight; |
__uwchar_t ui_weight; /* undefined or invalid */ |
int colitem; |
int weightidx; |
int rule; |
size_t position; |
/* should be wchar_t. if wchar < 0 do EILSEQ? */ |
__uwchar_t *cip; |
__uwchar_t ci_pending[MAX_PENDING]; /* nul-terminated */ |
|
char *back_buf; |
char *bbe; /* end of back_buf (actual last... not 1 past end) */ |
char *bp; /* ptr into backbuf, NULL if not in backward mode */ |
char ibb[128]; |
size_t bb_size; |
|
int ru_pushed; |
} col_state_t; |
|
|
#define WEIGHT_MASK 0x3fffU |
#define RULE_MASK 0xc000U |
|
#define RULE_FORWARD (1 << 14) |
#define RULE_POSITION (1 << 15) |
|
#define UI_IDX (WEIGHT_MASK-6) |
#define POSIT_IDX (WEIGHT_MASK-5) |
#define RANGE_IDX (WEIGHT_MASK-4) |
#define UNDEF_IDX (WEIGHT_MASK-3) |
#define INVAL_IDX (WEIGHT_MASK-2) |
#define DITTO_IDX (WEIGHT_MASK-1) |
|
|
#undef TRACE |
#if 0 |
#define TRACE(X) printf X |
#else |
#define TRACE(X) ((void)0) |
#endif |
|
static int lookup(wchar_t wc __LOCALE_PARAM ) |
{ |
unsigned int sc, n, i0, i1; |
|
if (((__uwchar_t) wc) > 0xffffU) { |
return 0; |
} |
|
sc = wc & CUR_COLLATE->ti_mask; |
wc >>= CUR_COLLATE->ti_shift; |
n = wc & CUR_COLLATE->ii_mask; |
wc >>= CUR_COLLATE->ii_shift; |
|
i0 = CUR_COLLATE->wcs2colidt_tbl[wc]; |
i0 <<= CUR_COLLATE->ii_shift; |
i1 = CUR_COLLATE->wcs2colidt_tbl[CUR_COLLATE->ii_len + i0 + n]; |
i1 <<= CUR_COLLATE->ti_shift; |
return CUR_COLLATE->wcs2colidt_tbl[CUR_COLLATE->ii_len + CUR_COLLATE->ti_len + i1 + sc]; |
|
} |
|
static void init_col_state(col_state_t *cs, const Wchar *wcs) |
{ |
memset(cs, 0, sizeof(col_state_t)); |
cs->s = wcs; |
cs->bp = cs->back_buf = cs->ibb; |
cs->bb_size = 128; |
cs->bbe = cs->back_buf + (cs->bb_size -1); |
} |
|
static void next_weight(col_state_t *cs, int pass __LOCALE_PARAM ) |
{ |
int r, w, ru, ri, popping_backup_stack; |
ssize_t n; |
const uint16_t *p; |
#ifdef WANT_WIDE |
#define WC (*cs->s) |
#define N (1) |
#else /* WANT_WIDE */ |
wchar_t WC; |
size_t n0, nx; |
#define N n0 |
|
#endif /* WANT_WIDE */ |
|
do { |
|
if (cs->ru_pushed) { |
ru = cs->ru_pushed; |
TRACE(("ru_pushed = %d\n", ru)); |
cs->ru_pushed = 0; |
goto POSITION_SKIP; |
} |
|
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning should we walk pendings backwards? |
#endif |
if (cs->cip) { /* possible pending weight */ |
if ((r = *(cs->cip++)) == 0) { |
cs->cip = NULL; |
continue; |
} |
cs->weightidx = r & WEIGHT_MASK; |
assert(cs->weightidx); |
/* assert(cs->weightidx != WEIGHT_MASK); */ |
} else { /* get the next collation item from the string */ |
TRACE(("clearing popping flag\n")); |
popping_backup_stack = 0; |
|
IGNORE_LOOP: |
/* keep first pos as 0 for a sentinal */ |
if (*cs->bp) { /* pending backward chars */ |
POP_BACKUP: |
popping_backup_stack = 1; |
TRACE(("setting popping flag\n")); |
n = 0; |
if (*cs->bp > 0) { /* singles pending */ |
cs->s -= 1; |
if ((*cs->bp -= 1) == 0) { |
cs->bp -= 1; |
} |
} else { /* last was a multi */ |
cs->s += *cs->bp; |
cs->bp -= 1; |
} |
} else if (!*cs->s) { /* not in backward mode and end of string */ |
cs->weight = 0; |
return; |
} else { |
cs->position += 1; |
} |
|
BACK_LOOP: |
#ifdef WANT_WIDE |
n = 1; |
cs->colitem = r = lookup(*cs->s __LOCALE_ARG ); |
#else /* WANT_WIDE */ |
n = n0 = __locale_mbrtowc_l(&WC, cs->s, __LOCALE_PTR); |
if (n < 0) { |
__set_errno(EILSEQ); |
cs->weight = 0; |
return; |
} |
cs->colitem = r = lookup(WC __LOCALE_ARG ); |
#endif /* WANT_WIDE */ |
|
TRACE((" r=%d WC=%#lx\n", r, (unsigned long)(WC))); |
|
if (r > CUR_COLLATE->max_col_index) { /* starting char for one or more sequences */ |
p = CUR_COLLATE->multistart_tbl; |
p += p[r-CUR_COLLATE->max_col_index -1]; |
do { |
n = N; |
r = *p++; |
do { |
if (!*p) { /* found it */ |
cs->colitem = r; |
TRACE((" found multi %d\n", n)); |
goto FOUND; |
} |
#ifdef WANT_WIDE |
/* the lookup check here is safe since we're assured that *p is a valid colidx */ |
if (!cs->s[n] || (lookup(cs->s[n] __LOCALE_ARG ) != *p)) { |
do {} while (*p++); |
break; |
} |
++p; |
++n; |
#else /* WANT_WIDE */ |
if (cs->s[n]) { |
nx = __locale_mbrtowc_l(&WC, cs->s + n, __LOCALE_PTR); |
if (nx < 0) { |
__set_errno(EILSEQ); |
cs->weight = 0; |
return; |
} |
} |
if (!cs->s[n] || (lookup(WC __LOCALE_ARG ) != *p)) { |
do {} while (*p++); |
break; |
} |
++p; |
n += nx; /* Only gets here if cs->s[n] != 0, so nx is set. */ |
#endif /* WANT_WIDE */ |
} while (1); |
} while (1); |
} else if (r == 0) { /* illegal, undefined, or part of a range */ |
if ((CUR_COLLATE->range_count) |
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning .. need to introduce range as a collating item? |
#endif |
&& (((__uwchar_t)(WC - CUR_COLLATE->range_low)) <= CUR_COLLATE->range_count) |
) { /* part of a range */ |
/* Note: cs->colitem = 0 already. */ |
TRACE((" found range\n")); |
ru = CUR_COLLATE->ruletable[CUR_COLLATE->range_rule_offset*CUR_COLLATE->MAX_WEIGHTS + pass]; |
assert((ru & WEIGHT_MASK) != DITTO_IDX); |
if ((ru & WEIGHT_MASK) == WEIGHT_MASK) { |
ru = (ru & RULE_MASK) | RANGE_IDX; |
cs->weight = CUR_COLLATE->range_base_weight + (WC - CUR_COLLATE->range_low); |
} |
goto RANGE_SKIP_TO; |
} else if (((__uwchar_t)(WC)) <= 0x7fffffffUL) { /* legal but undefined */ |
UNDEFINED: |
/* Note: cs->colitem = 0 already. */ |
ri = CUR_COLLATE->undefined_idx; |
assert(ri != 0); /* implicit undefined isn't supported */ |
|
TRACE((" found explicit UNDEFINED\n")); |
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning right now single weight locales do not support .. |
#endif |
if (CUR_COLLATE->num_weights == 1) { |
TRACE((" single weight UNDEFINED\n")); |
cs->weightidx = RANGE_IDX; |
cs->weight = ri; |
cs->s += n; |
goto PROCESS_WEIGHT; |
} |
|
ri = CUR_COLLATE->index2ruleidx[ri - 1]; |
ru = CUR_COLLATE->ruletable[ri * CUR_COLLATE->MAX_WEIGHTS + pass]; |
assert((ru & WEIGHT_MASK) != WEIGHT_MASK); /* TODO: handle ".." */ |
if ((ru & WEIGHT_MASK) == DITTO_IDX) { |
cs->colitem = CUR_COLLATE->undefined_idx; |
} |
goto RANGE_SKIP_TO; |
} else { /* illegal */ |
TRACE((" found illegal\n")); |
__set_errno(EINVAL); |
/* We put all illegals in the same equiv class with maximal weight, |
* and ignore them after the first pass. */ |
if (pass > 0) { |
cs->s += n; |
goto IGNORE_LOOP; |
} |
ru = (RULE_FORWARD | RANGE_IDX); |
cs->weight = 0xffffU; |
goto RANGE_SKIP_TO; |
} |
} else if (CUR_COLLATE->num_weights == 1) { |
TRACE((" single weight\n")); |
cs->weightidx = RANGE_IDX; |
cs->weight = cs->colitem; |
cs->s += n; |
goto PROCESS_WEIGHT; |
} else { |
TRACE((" normal\n")); |
} |
|
/* if we get here, it is a normal char either singlely weighted, undefined, or in a range */ |
FOUND: |
ri = CUR_COLLATE->index2ruleidx[cs->colitem - 1]; |
TRACE((" ri=%d ", ri)); |
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning make sure this is correct |
#endif |
if (!ri) { |
TRACE(("NOT IN THIS LOCALE\n")); |
goto UNDEFINED; |
} |
ru = CUR_COLLATE->ruletable[ri * CUR_COLLATE->MAX_WEIGHTS + pass]; |
|
RANGE_SKIP_TO: |
|
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning ignoreables probably should not interrupt backwards processing, but this is wrong |
#endif |
/* if (!(ru & WEIGHT_MASK)) { */ |
/* TRACE(("IGNORE\n")); */ |
/* cs->s += n; */ |
/* continue; */ |
/* } */ |
|
|
TRACE((" rule = %#x weight = %#x popping = %d s = %p eob = %p\n", |
ru & RULE_MASK, ru & WEIGHT_MASK, popping_backup_stack, |
cs->s, cs->eob)); |
/* now we need to check if we're going backwards... */ |
|
if (!popping_backup_stack) { |
if (!(ru & RULE_MASK)) { /* backward */ |
TRACE(("backwards\n")); |
assert(cs->bp <= cs->bbe); |
if (cs->bp == cs->bbe) { |
if (cs->back_buf == cs->ibb) { /* was using internal buffer */ |
cs->bp = malloc(cs->bb_size + 128); |
if (!cs->bp) { |
__set_errno(ENOMEM); |
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning what to do here? |
#endif |
cs->weight = 0; |
return; |
} |
memcpy(cs->bp, cs->back_buf, cs->bb_size); |
|
} else { |
cs->bp = realloc(cs->back_buf, cs->bb_size + 128); |
if (!cs->bp) { |
__set_errno(ENOMEM); |
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning what to do here? |
#endif |
cs->weight = 0; |
return; |
} |
} |
cs->bb_size += 128; |
cs->bbe = cs->bp + (cs->bbe - cs->back_buf); |
cs->back_buf = cs->bp; |
cs->bp = cs->bbe; |
|
} |
if (n==1) { /* single char */ |
if (*cs->bp && (((unsigned char)(*cs->bp)) < CHAR_MAX)) { |
*cs->bp += 1; /* increment last single's count */ |
} else { /* last was a multi, or just starting */ |
if (!cs->bp) { |
cs->bp = cs->back_buf; |
} else { |
assert(cs->bp < cs->bbe); |
++cs->bp; |
} |
*cs->bp = 1; |
} |
} else { /* multichar */ |
assert(n>1); |
assert(cs->bp < cs->bbe); |
*++cs->bp = -n; |
} |
cs->s += n; |
if (*cs->s) { |
goto BACK_LOOP; |
} |
/* end-of-string so start popping */ |
cs->eob = cs->s; |
TRACE(("popping\n")); |
goto POP_BACKUP; |
} else if (*cs->bp) { /* was going backward but this element isn't */ |
/* discard current and use previous backward element */ |
assert(!cs->cip); |
cs->eob = cs->s; |
TRACE(("popping\n")); |
goto POP_BACKUP; |
} else { /* was and still going forward */ |
TRACE(("forwards\n")); |
if ((ru & (RULE_POSITION|WEIGHT_MASK)) > RULE_POSITION) { |
assert(ru & WEIGHT_MASK); |
cs->ru_pushed = ru; |
cs->weight = cs->position; |
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning devel code |
#endif |
cs->position = 0; /* reset to reduce size for strcoll? */ |
cs->s += n; |
cs->weightidx = RANGE_IDX; |
goto PROCESS_WEIGHT; |
} |
} |
} else { /* popping backwards stack */ |
TRACE(("popping (continued)\n")); |
if (!*cs->bp) { |
cs->s = cs->eob; |
} |
cs->s -= n; |
} |
|
cs->s += n; |
POSITION_SKIP: |
cs->weightidx = ru & WEIGHT_MASK; |
cs->rule = ru & RULE_MASK; |
} |
|
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning for pending we only want the weight... _not_ the rule |
#endif |
if (!cs->weightidx) { /* ignore */ |
continue; |
} |
|
PROCESS_WEIGHT: |
assert(cs->weightidx); |
|
|
if (((unsigned int)(cs->weightidx - UI_IDX)) <= (INVAL_IDX-UI_IDX)) { |
if (cs->weightidx == UI_IDX) { |
cs->weight = cs->ui_weight; |
} |
return; |
} |
|
assert(cs->weightidx != WEIGHT_MASK); |
if (cs->weightidx == DITTO_IDX) { /* want the weight of the current collating item */ |
TRACE(("doing ditto\n")); |
w = CUR_COLLATE->index2weight[cs->colitem -1]; |
} else if (cs->weightidx <= CUR_COLLATE->max_col_index) { /* normal */ |
TRACE(("doing normal\n")); |
w = CUR_COLLATE->index2weight[cs->weightidx -1]; |
} else { /* a string */ |
TRACE(("doing string\n")); |
assert(!(cs->weightidx & RULE_MASK)); |
/* note: iso14561 allows null string here */ |
p = CUR_COLLATE->weightstr + (cs->weightidx - (CUR_COLLATE->max_col_index + 2)); |
if (*p & WEIGHT_MASK) { |
r = 0; |
do { |
assert(r < MAX_PENDING); |
cs->ci_pending[r++] = *p++; |
} while (*p & WEIGHT_MASK); |
cs->cip = cs->ci_pending; |
} |
continue; |
} |
|
cs->weight = w; |
return; |
} while (1); |
} |
|
int __XL(wcscoll) (const Wchar *s0, const Wchar *s1 __LOCALE_PARAM ) |
{ |
col_state_t ws[2]; |
int pass; |
|
if (!CUR_COLLATE->num_weights) { /* C locale */ |
#ifdef WANT_WIDE |
return wcscmp(s0, s1); |
#else /* WANT_WIDE */ |
return strcmp(s0, s1); |
#endif /* WANT_WIDE */ |
} |
|
pass = 0; |
do { /* loop through the weights levels */ |
init_col_state(ws, s0); |
init_col_state(ws+1, s1); |
do { /* loop through the strings */ |
/* for each string, get the next weight */ |
next_weight(ws, pass __LOCALE_ARG ); |
next_weight(ws+1, pass __LOCALE_ARG ); |
TRACE(("w0=%lu w1=%lu\n", |
(unsigned long) ws[0].weight, |
(unsigned long) ws[1].weight)); |
|
if (ws[0].weight != ws[1].weight) { |
return ws[0].weight - ws[1].weight; |
} |
} while (ws[0].weight); |
} while (++pass < CUR_COLLATE->num_weights); |
|
return 0; |
} |
|
__XL_ALIAS(wcscoll) |
|
#ifdef WANT_WIDE |
|
size_t __XL(wcsxfrm)(wchar_t *__restrict ws1, const wchar_t *__restrict ws2, |
size_t n __LOCALE_PARAM ) |
{ |
col_state_t cs; |
size_t count; |
int pass; |
|
if (!CUR_COLLATE->num_weights) { /* C locale */ |
return __wcslcpy(ws1, ws2, n); |
} |
|
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning handle empty string as a special case |
#endif |
|
count = pass = 0; |
do { /* loop through the weights levels */ |
init_col_state(&cs, ws2); |
do { /* loop through the string */ |
next_weight(&cs, pass __LOCALE_ARG ); |
TRACE(("weight=%lu (%#lx)\n", (unsigned long) cs.weight, (unsigned long) cs.weight)); |
if (count < n) { |
ws1[count] = cs.weight +1; |
} |
++count; |
TRACE(("--------------------------------------------\n")); |
} while (cs.weight); |
if (count <= n) { /* overwrite the trailing 0 end-of-pass marker */ |
ws1[count-1] = 1; |
} |
TRACE(("-------------------- pass %d --------------------\n", pass)); |
} while (++pass < CUR_COLLATE->num_weights); |
if (count <= n) { /* oops... change it back */ |
ws1[count-1] = 0; |
} |
return count-1; |
} |
|
__XL_ALIAS(wcsxfrm) |
|
#else /* WANT_WIDE */ |
|
static const unsigned long bound[] = { |
1UL << 7, |
1UL << 11, |
1UL << 16, |
1UL << 21, |
1UL << 26, |
}; |
|
static unsigned char first[] = { |
0x0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc |
}; |
|
/* Use an extension of UTF-8 to store a 32 bit val in max 6 bytes. */ |
|
static size_t store(unsigned char *s, size_t count, size_t n, __uwchar_t weight) |
{ |
int i, r; |
|
i = 0; |
do { |
if (weight < bound[i]) { |
break; |
} |
} while (++i < sizeof(bound)/sizeof(bound[0])); |
|
r = i+1; |
if (i + count < n) { |
s += count; |
s[0] = first[i]; |
while (i) { |
s[i] = 0x80 | (weight & 0x3f); |
weight >>= 6; |
--i; |
} |
s[0] |= weight; |
} |
|
return r; |
} |
|
size_t __XL(strxfrm)(char *__restrict ws1, const char *__restrict ws2, size_t n |
__LOCALE_PARAM ) |
{ |
col_state_t cs; |
size_t count, inc; |
int pass; |
|
if (!CUR_COLLATE->num_weights) { /* C locale */ |
return strlcpy(ws1, ws2, n); |
} |
|
#ifdef __UCLIBC_MJN3_ONLY__ |
#warning handle empty string as a special case |
#endif |
|
inc = count = pass = 0; |
do { /* loop through the weights levels */ |
init_col_state(&cs, ws2); |
do { /* loop through the string */ |
next_weight(&cs, pass __LOCALE_ARG ); |
TRACE(("weight=%lu (%#lx)\n", (unsigned long) cs.weight, (unsigned long) cs.weight)); |
inc = store((unsigned char *)ws1, count, n, cs.weight + 1); |
count += inc; |
TRACE(("--------------------------------------------\n")); |
} while (cs.weight); |
/* overwrite the trailing 0 end-of-pass marker */ |
assert(inc == 1); |
if (count <= n) { |
ws1[count-1] = 1; |
} |
TRACE(("-------------------- pass %d --------------------\n", pass)); |
} while (++pass < CUR_COLLATE->num_weights); |
if (count <= n) { /* oops... change it back */ |
ws1[count-1] = 0; |
} |
return count-1; |
} |
|
__XL_ALIAS(strxfrm) |
|
#endif /* WANT_WIDE */ |
|
#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ |
|
#endif /* defined(L_strxfrm) || defined(L_strxfrm_l) || defined(L_wcsxfrm) || defined(L_wcsxfrm_l) */ |
|
#endif /* __LOCALE_C_ONLY */ |
/**********************************************************************/ |