diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-05-30 21:03:17 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-05-30 21:03:17 +0000 |
commit | b69338f9f8ae2ae957949a0f4af9749ebb4adc3f (patch) | |
tree | c29019589ce21007d1ff99dd74d3115f19dbd3f4 /firmware/common/strncpy.c | |
parent | 80361f88818ad1ce2ebc00a10f7aa8de1605b3a5 (diff) | |
download | rockbox-b69338f9f8ae2ae957949a0f4af9749ebb4adc3f.tar.gz rockbox-b69338f9f8ae2ae957949a0f4af9749ebb4adc3f.zip |
Added code from libc instead of requiring newlib
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@835 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common/strncpy.c')
-rw-r--r-- | firmware/common/strncpy.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/firmware/common/strncpy.c b/firmware/common/strncpy.c new file mode 100644 index 0000000000..7c1973ba66 --- /dev/null +++ b/firmware/common/strncpy.c | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | FUNCTION | ||
3 | <<strncpy>>---counted copy string | ||
4 | |||
5 | INDEX | ||
6 | strncpy | ||
7 | |||
8 | ANSI_SYNOPSIS | ||
9 | #include <string.h> | ||
10 | char *strncpy(char *<[dst]>, const char *<[src]>, size_t <[length]>); | ||
11 | |||
12 | TRAD_SYNOPSIS | ||
13 | #include <string.h> | ||
14 | char *strncpy(<[dst]>, <[src]>, <[length]>) | ||
15 | char *<[dst]>; | ||
16 | char *<[src]>; | ||
17 | size_t <[length]>; | ||
18 | |||
19 | DESCRIPTION | ||
20 | <<strncpy>> copies not more than <[length]> characters from the | ||
21 | the string pointed to by <[src]> (including the terminating | ||
22 | null character) to the array pointed to by <[dst]>. If the | ||
23 | string pointed to by <[src]> is shorter than <[length]> | ||
24 | characters, null characters are appended to the destination | ||
25 | array until a total of <[length]> characters have been | ||
26 | written. | ||
27 | |||
28 | RETURNS | ||
29 | This function returns the initial value of <[dst]>. | ||
30 | |||
31 | PORTABILITY | ||
32 | <<strncpy>> is ANSI C. | ||
33 | |||
34 | <<strncpy>> requires no supporting OS subroutines. | ||
35 | |||
36 | QUICKREF | ||
37 | strncpy ansi pure | ||
38 | */ | ||
39 | |||
40 | #include <string.h> | ||
41 | #include <limits.h> | ||
42 | |||
43 | /*SUPPRESS 560*/ | ||
44 | /*SUPPRESS 530*/ | ||
45 | |||
46 | /* Nonzero if either X or Y is not aligned on a "long" boundary. */ | ||
47 | #define UNALIGNED(X, Y) \ | ||
48 | (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) | ||
49 | |||
50 | #if LONG_MAX == 2147483647L | ||
51 | #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) | ||
52 | #else | ||
53 | #if LONG_MAX == 9223372036854775807L | ||
54 | /* Nonzero if X (a long int) contains a NULL byte. */ | ||
55 | #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) | ||
56 | #else | ||
57 | #error long int is not a 32bit or 64bit type. | ||
58 | #endif | ||
59 | #endif | ||
60 | |||
61 | #ifndef DETECTNULL | ||
62 | #error long int is not a 32bit or 64bit byte | ||
63 | #endif | ||
64 | |||
65 | #define TOO_SMALL(LEN) ((LEN) < sizeof (long)) | ||
66 | |||
67 | char * | ||
68 | _DEFUN (strncpy, (dst0, src0), | ||
69 | char *dst0 _AND | ||
70 | _CONST char *src0 _AND | ||
71 | size_t count) | ||
72 | { | ||
73 | #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) | ||
74 | char *dscan; | ||
75 | _CONST char *sscan; | ||
76 | |||
77 | dscan = dst0; | ||
78 | sscan = src0; | ||
79 | while (count > 0) | ||
80 | { | ||
81 | --count; | ||
82 | if ((*dscan++ = *sscan++) == '\0') | ||
83 | break; | ||
84 | } | ||
85 | while (count-- > 0) | ||
86 | *dscan++ = '\0'; | ||
87 | |||
88 | return dst0; | ||
89 | #else | ||
90 | char *dst = dst0; | ||
91 | _CONST char *src = src0; | ||
92 | long *aligned_dst; | ||
93 | _CONST long *aligned_src; | ||
94 | |||
95 | /* If SRC and DEST is aligned and count large enough, then copy words. */ | ||
96 | if (!UNALIGNED (src, dst) && !TOO_SMALL (count)) | ||
97 | { | ||
98 | aligned_dst = (long*)dst; | ||
99 | aligned_src = (long*)src; | ||
100 | |||
101 | /* SRC and DEST are both "long int" aligned, try to do "long int" | ||
102 | sized copies. */ | ||
103 | while (count >= sizeof (long int) && !DETECTNULL(*aligned_src)) | ||
104 | { | ||
105 | count -= sizeof (long int); | ||
106 | *aligned_dst++ = *aligned_src++; | ||
107 | } | ||
108 | |||
109 | dst = (char*)aligned_dst; | ||
110 | src = (char*)aligned_src; | ||
111 | } | ||
112 | |||
113 | while (count > 0) | ||
114 | { | ||
115 | --count; | ||
116 | if ((*dst++ = *src++) == '\0') | ||
117 | break; | ||
118 | } | ||
119 | |||
120 | while (count-- > 0) | ||
121 | *dst++ = '\0'; | ||
122 | |||
123 | return dst0; | ||
124 | #endif /* not PREFER_SIZE_OVER_SPEED */ | ||
125 | } | ||