1 /* @(#)movecbytes.c 1.2 16/11/05 Copyright 2016 J. Schilling */
2 /*
3 * move data, stop if character c is copied
4 *
5 * Copyright (c) 2016 J. Schilling
6 */
7 /*
8 * The contents of this file are subject to the terms of the
9 * Common Development and Distribution License, Version 1.0 only
10 * (the "License"). You may not use this file except in compliance
11 * with the License.
12 *
13 * See the file CDDL.Schily.txt in this distribution for details.
14 * A copy of the CDDL is also available via the Internet at
15 * http://www.opensource.org/licenses/cddl1.txt
16 *
17 * When distributing Covered Code, include this CDDL HEADER in each
18 * file and include the License file CDDL.Schily.txt from this distribution.
19 */
20
21 #include <schily/standard.h>
22 #include <schily/types.h>
23 #include <schily/schily.h>
24
25 #define DO8(a) a; a; a; a; a; a; a; a;
26
27 /*
28 * movecbytes(from, to, c, cnt) is the same as memccpy(to, from, c, cnt)
29 */
30 EXPORT char *
movecbytes(fromv,tov,c,cnt)31 movecbytes(fromv, tov, c, cnt)
32 const void *fromv;
33 void *tov;
34 register int c;
35 size_t cnt;
36 {
37 register const char *from = fromv;
38 register char *to = tov;
39 register size_t n;
40
41 if ((n = cnt) == 0)
42 return (NULL);
43
44 #define separate_code
45 #ifdef separate_code
46 while (n >= 8) {
47 /* BEGIN CSTYLED */
48 DO8(
49 if ((*to++ = *from++) == (char)c)
50 return (to);
51 );
52 /* END CSTYLED */
53 n -= 8;
54 }
55
56 switch (n) {
57
58 case 7: if ((*to++ = *from++) == (char)c)
59 return (to);
60 case 6: if ((*to++ = *from++) == (char)c)
61 return (to);
62 case 5: if ((*to++ = *from++) == (char)c)
63 return (to);
64 case 4: if ((*to++ = *from++) == (char)c)
65 return (to);
66 case 3: if ((*to++ = *from++) == (char)c)
67 return (to);
68 case 2: if ((*to++ = *from++) == (char)c)
69 return (to);
70 case 1: if ((*to++ = *from++) == (char)c)
71 return (to);
72 }
73 #else
74 /*
75 * This variant should be as fast as the code above but
76 * half the size. Unfortunately, most compilers do not optmize
77 * it correctly.
78 */
79 int rest = n % 8;
80
81 n -= rest;
82
83 switch (rest) {
84
85 case 0: while (n != 0) {
86 n -= 8;
87 if ((*to++ = *from++) == (char)c)
88 return (to);
89 case 7: if ((*to++ = *from++) == (char)c)
90 return (to);
91 case 6: if ((*to++ = *from++) == (char)c)
92 return (to);
93 case 5: if ((*to++ = *from++) == (char)c)
94 return (to);
95 case 4: if ((*to++ = *from++) == (char)c)
96 return (to);
97 case 3: if ((*to++ = *from++) == (char)c)
98 return (to);
99 case 2: if ((*to++ = *from++) == (char)c)
100 return (to);
101 case 1: if ((*to++ = *from++) == (char)c)
102 return (to);
103 }
104 }
105 #endif
106 return (NULL);
107 }
108