1/* Test of uN_move() functions.
2   Copyright (C) 2010 Free Software Foundation, Inc.
3
4   This program is free software: you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 3 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17/* Written by Bruno Haible <bruno@clisp.org>, 2010.  */
18
19int
20main ()
21{
22  /* Test copying operations with disjoint source and destination.  */
23  {
24    static const UNIT src[] = { 'c', 'l', 'i', 'm', 'a', 't', 'e' };
25    size_t n;
26
27    for (n = 0; n <= SIZEOF (src); n++)
28      {
29        UNIT dest[1 + SIZEOF (src) + 1] =
30          { MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC, MAGIC };
31        UNIT *ret;
32        size_t i;
33
34        ret = U_MOVE (dest + 1, src, n);
35        ASSERT (ret == dest + 1);
36        ASSERT (dest[0] == MAGIC);
37        for (i = 0; i < n; i++)
38          ASSERT (dest[1 + i] == src[i]);
39        ASSERT (dest[1 + n] == MAGIC);
40      }
41  }
42
43  /* Test copying operations with overlap, in-place.  */
44  {
45    static const UNIT src[] = { 'c', 'l', 'i', 'm', 'a', 't', 'e' };
46    size_t n;
47
48    for (n = 0; n <= SIZEOF (src); n++)
49      {
50        UNIT dest[1 + SIZEOF (src) + 1];
51        UNIT *ret;
52        size_t i;
53
54        dest[0] = MAGIC;
55        for (i = 0; i < n; i++)
56          dest[1 + i] = src[i];
57        dest[1 + n] = MAGIC;
58
59        ret = U_MOVE (dest + 1, dest + 1, n);
60        ASSERT (ret == dest + 1);
61        ASSERT (dest[0] == MAGIC);
62        for (i = 0; i < n; i++)
63          ASSERT (dest[1 + i] == src[i]);
64        ASSERT (dest[1 + n] == MAGIC);
65      }
66  }
67
68  /* Test copying operations with overlap, moving downward.  */
69  {
70    static const UNIT src[] = { 'c', 'l', 'i', 'm', 'a', 't', 'e' };
71    static const UNIT src2[] = { 'C', 'L', 'I', 'M', 'A', 'T', 'E' };
72    size_t d;
73
74    ASSERT (SIZEOF (src) == SIZEOF (src2));
75    for (d = 0; d <= SIZEOF (src); d++)
76      {
77        size_t n;
78
79        for (n = 0; n <= SIZEOF (src); n++)
80          {
81            UNIT dest[1 + 2 * SIZEOF (src) + 1];
82            UNIT *ret;
83            size_t i;
84
85            dest[0] = MAGIC;
86            for (i = 0; i < SIZEOF (src2); i++)
87              dest[1 + i] = src2[i];
88            for (i = 0; i < SIZEOF (src); i++)
89              dest[1 + SIZEOF (src) + i] = src[i];
90            dest[1 + 2 * SIZEOF (src)] = MAGIC;
91
92            ret =
93              U_MOVE (dest + 1 + SIZEOF (src) - d, dest + 1 + SIZEOF (src), n);
94            ASSERT (ret == dest + 1 + SIZEOF (src) - d);
95            ASSERT (dest[0] == MAGIC);
96            for (i = 0; i < SIZEOF (src) - d; i++)
97              ASSERT (dest[1 + i] == src2[i]);
98            for (i = 0; i < n; i++)
99              ASSERT (dest[1 + SIZEOF (src) - d + i] == src[i]);
100            for (i = SIZEOF (src) - d + n; i < SIZEOF (src2); i++)
101              ASSERT (dest[1 + i] == src2[i]);
102            for (i = (n >= d ? n - d : 0); i < SIZEOF (src); i++)
103              ASSERT (dest[1 + SIZEOF (src) + i] == src[i]);
104            ASSERT (dest[1 + 2 * SIZEOF (src)] == MAGIC);
105          }
106      }
107  }
108
109  /* Test copying operations with overlap, moving upward.  */
110  {
111    static const UNIT src[] = { 'c', 'l', 'i', 'm', 'a', 't', 'e' };
112    static const UNIT src2[] = { 'C', 'L', 'I', 'M', 'A', 'T', 'E' };
113    size_t d;
114
115    ASSERT (SIZEOF (src) == SIZEOF (src2));
116    for (d = 0; d <= SIZEOF (src); d++)
117      {
118        size_t n;
119
120        for (n = 0; n <= SIZEOF (src); n++)
121          {
122            UNIT dest[1 + 2 * SIZEOF (src) + 1];
123            UNIT *ret;
124            size_t i;
125
126            dest[0] = MAGIC;
127            for (i = 0; i < SIZEOF (src); i++)
128              dest[1 + i] = src[i];
129            for (i = 0; i < SIZEOF (src2); i++)
130              dest[1 + SIZEOF (src) + i] = src2[i];
131            dest[1 + 2 * SIZEOF (src)] = MAGIC;
132
133            ret = U_MOVE (dest + 1 + d, dest + 1, n);
134            ASSERT (ret == dest + 1 + d);
135            ASSERT (dest[0] == MAGIC);
136            for (i = 0; i < d; i++)
137              ASSERT (dest[1 + i] == src[i]);
138            for (i = 0; i < n; i++)
139              ASSERT (dest[1 + d + i] == src[i]);
140            for (i = d + n; i < SIZEOF (src); i++)
141              ASSERT (dest[1 + i] == src[i]);
142            for (i = (d + n >= SIZEOF (src) ? d + n - SIZEOF (src) : 0);
143                 i < SIZEOF (src2);
144                 i++)
145              ASSERT (dest[1 + SIZEOF (src) + i] == src2[i]);
146            ASSERT (dest[1 + 2 * SIZEOF (src)] == MAGIC);
147          }
148      }
149  }
150
151  return 0;
152}
153