add a CVS snapshot, to thoroughly test on the Debian side
[alioth/jupp.git] / blocks.c
1 /* $MirOS: contrib/code/jupp/blocks.c,v 1.4 2012/06/08 16:55:27 tg Exp $ */
2 /*
3  *      Fast block move/copy subroutines
4  *      Copyright
5  *              (C) 1992 Joseph H. Allen
6  *
7  *      This file is part of JOE (Joe's Own Editor)
8  */
9 #include "config.h"
10
11 /* This module requires ALIGNED and SIZEOF_INT to be defined correctly */
12
13 #include "blocks.h"
14
15 #define BITS 8
16
17 #if SIZEOF_INT == 8
18 #  define SHFT 3
19 #elif SIZEOF_INT == 4
20 #  define SHFT 2
21 #elif SIZEOF_INT == 2
22 #  define SHFT 1
23 #endif
24
25 /* Set 'sz' 'int's beginning at 'd' to the value 'c' */
26 /* Returns address of block.  Does nothing if 'sz' equals zero */
27
28 int *msetI(void *dest, int c, int sz)
29 {
30         int     *d = dest;
31         int     *orgd = dest;
32
33         while (sz >= 16) {
34                 d[0] = c;
35                 d[1] = c;
36                 d[2] = c;
37                 d[3] = c;
38                 d[4] = c;
39                 d[5] = c;
40                 d[6] = c;
41                 d[7] = c;
42                 d[8] = c;
43                 d[9] = c;
44                 d[10] = c;
45                 d[11] = c;
46                 d[12] = c;
47                 d[13] = c;
48                 d[14] = c;
49                 d[15] = c;
50                 d += 16;
51                 sz -= 16;
52         }
53         switch (sz) {
54         case 15:        d[14] = c;
55         case 14:        d[13] = c;
56         case 13:        d[12] = c;
57         case 12:        d[11] = c;
58         case 11:        d[10] = c;
59         case 10:        d[9] = c;
60         case 9:         d[8] = c;
61         case 8:         d[7] = c;
62         case 7:         d[6] = c;
63         case 6:         d[5] = c;
64         case 5:         d[4] = c;
65         case 4:         d[3] = c;
66         case 3:         d[2] = c;
67         case 2:         d[1] = c;
68         case 1:         d[0] = c;
69         case 0:         /* do nothing */;
70         }
71         return orgd;
72 }
73
74 /* Set 'sz' 'int's beginning at 'd' to the value 'c' */
75 /* Returns address of block.  Does nothing if 'sz' equals zero */
76
77 void **msetP(void **d, void *c, int sz)
78 {
79         void    **orgd = d;
80
81         while (sz >= 16) {
82                 d[0] = c;
83                 d[1] = c;
84                 d[2] = c;
85                 d[3] = c;
86                 d[4] = c;
87                 d[5] = c;
88                 d[6] = c;
89                 d[7] = c;
90                 d[8] = c;
91                 d[9] = c;
92                 d[10] = c;
93                 d[11] = c;
94                 d[12] = c;
95                 d[13] = c;
96                 d[14] = c;
97                 d[15] = c;
98                 d += 16;
99                 sz -= 16;
100         }
101         switch (sz) {
102         case 15:        d[14] = c;
103         case 14:        d[13] = c;
104         case 13:        d[12] = c;
105         case 12:        d[11] = c;
106         case 11:        d[10] = c;
107         case 10:        d[9] = c;
108         case 9:         d[8] = c;
109         case 8:         d[7] = c;
110         case 7:         d[6] = c;
111         case 6:         d[5] = c;
112         case 5:         d[4] = c;
113         case 4:         d[3] = c;
114         case 3:         d[2] = c;
115         case 2:         d[1] = c;
116         case 1:         d[0] = c;
117         case 0:         /* do nothing */;
118         }
119         return orgd;
120 }
121
122 /* Set 'sz' 'char's beginning at 'd' to the value 'c' */
123 /* Returns address of block.  Does nothing if 'sz' equals zero */
124
125 unsigned char *mset(void *dest, unsigned char c, int sz)
126 {
127         unsigned char   *d = dest;
128         unsigned char   *orgd = dest;
129
130         if (sz < 16) {
131                 switch (sz) {
132                 case 15:        d[14] = c;
133                 case 14:        d[13] = c;
134                 case 13:        d[12] = c;
135                 case 12:        d[11] = c;
136                 case 11:        d[10] = c;
137                 case 10:        d[9] = c;
138                 case 9:         d[8] = c;
139                 case 8:         d[7] = c;
140                 case 7:         d[6] = c;
141                 case 6:         d[5] = c;
142                 case 5:         d[4] = c;
143                 case 4:         d[3] = c;
144                 case 3:         d[2] = c;
145                 case 2:         d[1] = c;
146                 case 1:         d[0] = c;
147                 case 0:         /* do nothing */;
148                 }
149         } else {
150                 unsigned z = SIZEOF_INT - ((unsigned long)d & (SIZEOF_INT - 1));
151
152                 if (z != SIZEOF_INT) {
153                         switch (z) {
154                         case 7:         d[6] = c;
155                         case 6:         d[5] = c;
156                         case 5:         d[4] = c;
157                         case 4:         d[3] = c;
158                         case 3:         d[2] = c;
159                         case 2:         d[1] = c;
160                         case 1:         d[0] = c;
161                         case 0:         /* do nothing */;
162                         }
163                         d += z;
164                         sz -= z;
165                 }
166                 msetI(d,
167 #if SIZEOF_INT >= 8
168                       (c << (BITS * 7)) + (c << (BITS * 6)) + (c << (BITS * 5)) + (c << (BITS * 4)) +
169 #endif
170 #if SIZEOF_INT >= 4
171                       (c << (BITS * 3)) + (c << (BITS * 2)) +
172 #endif
173 #if SIZEOF_INT >= 2
174                       (c << BITS) +
175 #endif
176                       c, sz >> SHFT);
177                 d += sz & ~(SIZEOF_INT - 1);
178                 switch (sz & (SIZEOF_INT - 1)) {
179                 case 7:         d[6] = c;
180                 case 6:         d[5] = c;
181                 case 5:         d[4] = c;
182                 case 4:         d[3] = c;
183                 case 3:         d[2] = c;
184                 case 2:         d[1] = c;
185                 case 1:         d[0] = c;
186                 case 0:         /* do nothing */;
187                 }
188         }
189         return orgd;
190 }
191
192 /* Copy a block of integers */
193 /* Copy from highest address to lowest */
194
195 static int *mbkwdI(void *dest, const void *src, int sz)
196 {
197         int     *d = dest;
198         const int *s = src;
199
200         if (d == s)
201                 return d;
202         d += sz;
203         s += sz;
204         while (sz >= 16) {
205                 d -= 16;
206                 s -= 16;
207                 d[15] = s[15];
208                 d[14] = s[14];
209                 d[13] = s[13];
210                 d[12] = s[12];
211                 d[11] = s[11];
212                 d[10] = s[10];
213                 d[9] = s[9];
214                 d[8] = s[8];
215                 d[7] = s[7];
216                 d[6] = s[6];
217                 d[5] = s[5];
218                 d[4] = s[4];
219                 d[3] = s[3];
220                 d[2] = s[2];
221                 d[1] = s[1];
222                 d[0] = s[0];
223                 sz -= 16;
224         }
225         d -= sz;
226         s -= sz;
227         switch (sz) {
228         case 15:        d[14] = s[14];
229         case 14:        d[13] = s[13];
230         case 13:        d[12] = s[12];
231         case 12:        d[11] = s[11];
232         case 11:        d[10] = s[10];
233         case 10:        d[9] = s[9];
234         case 9:         d[8] = s[8];
235         case 8:         d[7] = s[7];
236         case 7:         d[6] = s[6];
237         case 6:         d[5] = s[5];
238         case 5:         d[4] = s[4];
239         case 4:         d[3] = s[3];
240         case 3:         d[2] = s[2];
241         case 2:         d[1] = s[1];
242         case 1:         d[0] = s[0];
243         case 0:         /* do nothing */;
244         }
245         return d;
246 }
247
248 /* Copy a block of 'int's.  Copy from lowest address to highest */
249
250 static int *mfwrdI(void *dest, const void *src, int sz)
251 {
252         int     *d = dest;
253         const int *s = src;
254         int     *od = d;
255
256         if (s == d)
257                 return d;
258         while (sz >= 16) {
259                 d[0] = s[0];
260                 d[1] = s[1];
261                 d[2] = s[2];
262                 d[3] = s[3];
263                 d[4] = s[4];
264                 d[5] = s[5];
265                 d[6] = s[6];
266                 d[7] = s[7];
267                 d[8] = s[8];
268                 d[9] = s[9];
269                 d[10] = s[10];
270                 d[11] = s[11];
271                 d[12] = s[12];
272                 d[13] = s[13];
273                 d[14] = s[14];
274                 d[15] = s[15];
275                 s += 16;
276                 d += 16;
277                 sz -= 16;
278         }
279         s -= 15 - sz;
280         d -= 15 - sz;
281         switch (sz) {
282         case 15:        d[0] = s[0];
283         case 14:        d[1] = s[1];
284         case 13:        d[2] = s[2];
285         case 12:        d[3] = s[3];
286         case 11:        d[4] = s[4];
287         case 10:        d[5] = s[5];
288         case 9:         d[6] = s[6];
289         case 8:         d[7] = s[7];
290         case 7:         d[8] = s[8];
291         case 6:         d[9] = s[9];
292         case 5:         d[10] = s[10];
293         case 4:         d[11] = s[11];
294         case 3:         d[12] = s[12];
295         case 2:         d[13] = s[13];
296         case 1:         d[14] = s[14];
297         case 0:         /* do nothing */;
298         }
299         return od;
300 }
301
302 /* Copy the block of 'sz' bytes beginning at 's' to 'd'.  If 'sz' is zero or
303  * if 's'=='d', nothing happens.  The bytes at the highest address ('s'+'sz'-1)
304  * are copied before the ones at the lowest ('s') are.
305  */
306
307 static unsigned char *mbkwd(register unsigned char *d, register const unsigned char *s, register int sz)
308 {
309         if (s == d)
310                 return d;
311         s += sz;
312         d += sz;
313 #ifdef ALIGNED
314         if (sz >= 16)
315 #else
316         if (((unsigned long)s & (SIZEOF_INT - 1)) == ((unsigned long)d & (SIZEOF_INT - 1)) && sz >= 16)
317 #endif
318         {
319                 unsigned z = ((unsigned long) s & (SIZEOF_INT - 1));
320
321                 s -= z;
322                 d -= z;
323                 switch (z) {
324                 case 7:         d[6] = s[6];
325                 case 6:         d[5] = s[5];
326                 case 5:         d[4] = s[4];
327                 case 4:         d[3] = s[3];
328                 case 3:         d[2] = s[2];
329                 case 2:         d[1] = s[1];
330                 case 1:         d[0] = s[0];
331                 case 0:         /* do nothing */;
332                 }
333                 sz -= z;
334                 mbkwdI(d - (sz & ~(SIZEOF_INT - 1)), s - (sz & ~(SIZEOF_INT - 1)), sz >> SHFT);
335                 d -= sz;
336                 s -= sz;
337                 switch (sz & (SIZEOF_INT - 1)) {
338                 case 7:         d[6] = s[6];
339                 case 6:         d[5] = s[5];
340                 case 5:         d[4] = s[4];
341                 case 4:         d[3] = s[3];
342                 case 3:         d[2] = s[2];
343                 case 2:         d[1] = s[1];
344                 case 1:         d[0] = s[0];
345                 case 0:         /* do nothing */;
346                 }
347         } else {
348                 while (sz >= 16) {
349                         d -= 16;
350                         s -= 16;
351                         d[15] = s[15];
352                         d[14] = s[14];
353                         d[13] = s[13];
354                         d[12] = s[12];
355                         d[11] = s[11];
356                         d[10] = s[10];
357                         d[9] = s[9];
358                         d[8] = s[8];
359                         d[7] = s[7];
360                         d[6] = s[6];
361                         d[5] = s[5];
362                         d[4] = s[4];
363                         d[3] = s[3];
364                         d[2] = s[2];
365                         d[1] = s[1];
366                         d[0] = s[0];
367                         sz -= 16;
368                 }
369                 d -= sz;
370                 s -= sz;
371                 switch (sz) {
372                 case 15:        d[14] = s[14];
373                 case 14:        d[13] = s[13];
374                 case 13:        d[12] = s[12];
375                 case 12:        d[11] = s[11];
376                 case 11:        d[10] = s[10];
377                 case 10:        d[9] = s[9];
378                 case 9:         d[8] = s[8];
379                 case 8:         d[7] = s[7];
380                 case 7:         d[6] = s[6];
381                 case 6:         d[5] = s[5];
382                 case 5:         d[4] = s[4];
383                 case 4:         d[3] = s[3];
384                 case 3:         d[2] = s[2];
385                 case 2:         d[1] = s[1];
386                 case 1:         d[0] = s[0];
387                 case 0:         /* do nothing */;
388                 }
389         }
390         return d;
391 }
392
393 /* Copy the block of 'sz' bytes beginning at 's' to 'd'.  If 'sz' is zero or
394  * if 's'=='d', nothing happens.  The bytes at the lowest address ('s')
395  * are copied before the ones at the highest ('s'+'sz'-1) are.
396  */
397
398 static unsigned char *mfwrd(register unsigned char *d, register const unsigned char *s, register int sz)
399 {
400         unsigned char *od = d;
401
402         if (d == s)
403                 return d;
404 #ifdef ALIGNED
405         if (sz >= 16)
406 #else
407         if (((unsigned long)d & (SIZEOF_INT - 1)) == ((unsigned long)s & (SIZEOF_INT - 1)) && sz >= 16)
408 #endif
409         {
410                 unsigned z = ((unsigned long)s & (SIZEOF_INT - 1));
411
412                 if (z) {
413                         s -= z;
414                         d -= z;
415                         switch (SIZEOF_INT - z) {
416 #if SIZEOF_INT == 8
417                         case 7:         d[1] = s[1];
418                         case 6:         d[2] = s[2];
419                         case 5:         d[3] = s[3];
420                         case 4:         d[4] = s[4];
421                         case 3:         d[5] = s[5];
422                         case 2:         d[6] = s[6];
423                         case 1:         d[7] = s[7];
424                         case 0:         /* do nothing */;
425 #else
426 #if SIZEOF_INT == 4
427                         case 3:         d[1] = s[1];
428                         case 2:         d[2] = s[2];
429                         case 1:         d[3] = s[3];
430                         case 0:         /* do nothing */;
431 #else
432 #if SIZEOF_INT == 2
433                         case 1:         d[1] = s[1];
434                         case 0:         /* do nothing */;
435 #endif
436 #endif
437 #endif
438                         }
439                         s += SIZEOF_INT;
440                         d += SIZEOF_INT;
441                         sz -= SIZEOF_INT - z;
442                 }
443                 mfwrdI(d, s, sz >> SHFT);
444                 s += sz - (SIZEOF_INT - 1);
445                 d += sz - (SIZEOF_INT - 1);
446                 switch (sz & (SIZEOF_INT - 1)) {
447 #if SIZEOF_INT == 8
448                 case 7:         d[0] = s[0];
449                 case 6:         d[1] = s[1];
450                 case 5:         d[2] = s[2];
451                 case 4:         d[3] = s[3];
452                 case 3:         d[4] = s[4];
453                 case 2:         d[5] = s[5];
454                 case 1:         d[6] = s[6];
455                 case 0:         /* do nothing */;
456 #else
457 #if SIZEOF_INT == 4
458                 case 3:         d[0] = s[0];
459                 case 2:         d[1] = s[1];
460                 case 1:         d[2] = s[2];
461                 case 0:         /* do nothing */;
462 #else
463 #if SIZEOF_INT == 2
464                 case 1:         d[0] = s[0];
465                 case 0:         /* do nothing */;
466 #endif
467 #endif
468 #endif
469                 }
470         } else {
471                 while (sz >= 16) {
472                         d[0] = s[0];
473                         d[1] = s[1];
474                         d[2] = s[2];
475                         d[3] = s[3];
476                         d[4] = s[4];
477                         d[5] = s[5];
478                         d[6] = s[6];
479                         d[7] = s[7];
480                         d[8] = s[8];
481                         d[9] = s[9];
482                         d[10] = s[10];
483                         d[11] = s[11];
484                         d[12] = s[12];
485                         d[13] = s[13];
486                         d[14] = s[14];
487                         d[15] = s[15];
488                         s += 16;
489                         d += 16;
490                         sz -= 16;
491                 }
492                 s -= 15 - sz;
493                 d -= 15 - sz;
494                 switch (sz) {
495                 case 15:        d[0] = s[0];
496                 case 14:        d[1] = s[1];
497                 case 13:        d[2] = s[2];
498                 case 12:        d[3] = s[3];
499                 case 11:        d[4] = s[4];
500                 case 10:        d[5] = s[5];
501                 case 9:         d[6] = s[6];
502                 case 8:         d[7] = s[7];
503                 case 7:         d[8] = s[8];
504                 case 6:         d[9] = s[9];
505                 case 5:         d[10] = s[10];
506                 case 4:         d[11] = s[11];
507                 case 3:         d[12] = s[12];
508                 case 2:         d[13] = s[13];
509                 case 1:         d[14] = s[14];
510                 case 0:         /* do nothing */;
511                 }
512         }
513         return od;
514 }
515
516 void *mmove(void *d, const void *s, int sz)
517 {
518         if (d > s)
519                 mbkwd(d, s, sz);
520         else
521                 mfwrd(d, s, sz);
522         return d;
523 }
524
525 /* Utility to count number of lines within a segment */
526
527 int mcnt(register unsigned char *blk, register unsigned char c, int size)
528 {
529         register int nlines = 0;
530
531         while (size >= 16) {
532                 if (blk[0] == c) ++nlines;
533                 if (blk[1] == c) ++nlines;
534                 if (blk[2] == c) ++nlines;
535                 if (blk[3] == c) ++nlines;
536                 if (blk[4] == c) ++nlines;
537                 if (blk[5] == c) ++nlines;
538                 if (blk[6] == c) ++nlines;
539                 if (blk[7] == c) ++nlines;
540                 if (blk[8] == c) ++nlines;
541                 if (blk[9] == c) ++nlines;
542                 if (blk[10] == c) ++nlines;
543                 if (blk[11] == c) ++nlines;
544                 if (blk[12] == c) ++nlines;
545                 if (blk[13] == c) ++nlines;
546                 if (blk[14] == c) ++nlines;
547                 if (blk[15] == c) ++nlines;
548                 blk += 16;
549                 size -= 16;
550         }
551         switch (size) {
552         case 15:        if (blk[14] == c) ++nlines;
553         case 14:        if (blk[13] == c) ++nlines;
554         case 13:        if (blk[12] == c) ++nlines;
555         case 12:        if (blk[11] == c) ++nlines;
556         case 11:        if (blk[10] == c) ++nlines;
557         case 10:        if (blk[9] == c) ++nlines;
558         case 9:         if (blk[8] == c) ++nlines;
559         case 8:         if (blk[7] == c) ++nlines;
560         case 7:         if (blk[6] == c) ++nlines;
561         case 6:         if (blk[5] == c) ++nlines;
562         case 5:         if (blk[4] == c) ++nlines;
563         case 4:         if (blk[3] == c) ++nlines;
564         case 3:         if (blk[2] == c) ++nlines;
565         case 2:         if (blk[1] == c) ++nlines;
566         case 1:         if (blk[0] == c) ++nlines;
567         case 0:         /* do nothing */;
568         }
569         return nlines;
570 }