Logo Search packages:      
Sourcecode: joe version File versions  Download package

blocks.c

/*
 *    Fast block move/copy subroutines
 *    Copyright
 *          (C) 1992 Joseph H. Allen
 *
 *    This file is part of JOE (Joe's Own Editor)
 */
#include "config.h"

/* This module requires ALIGNED and SIZEOF_INT to be defined correctly */

#include "blocks.h"

#define BITS 8

#if SIZEOF_INT == 8
#  define SHFT 3
#elif SIZEOF_INT == 4
#  define SHFT 2
#elif SIZEOF_INT == 2
#  define SHFT 1
#endif

/* Set 'sz' 'int's beginning at 'd' to the value 'c' */
/* Returns address of block.  Does nothing if 'sz' equals zero */

int *msetI(void *dest, int c, int sz)
{
      int   *d = dest;
      int   *orgd = dest;

      while (sz >= 16) {
            d[0] = c;
            d[1] = c;
            d[2] = c;
            d[3] = c;
            d[4] = c;
            d[5] = c;
            d[6] = c;
            d[7] = c;
            d[8] = c;
            d[9] = c;
            d[10] = c;
            d[11] = c;
            d[12] = c;
            d[13] = c;
            d[14] = c;
            d[15] = c;
            d += 16;
            sz -= 16;
      }
      switch (sz) {
      case 15:    d[14] = c;
      case 14:    d[13] = c;
      case 13:    d[12] = c;
      case 12:    d[11] = c;
      case 11:    d[10] = c;
      case 10:    d[9] = c;
      case 9:           d[8] = c;
      case 8:           d[7] = c;
      case 7:           d[6] = c;
      case 6:           d[5] = c;
      case 5:           d[4] = c;
      case 4:           d[3] = c;
      case 3:           d[2] = c;
      case 2:           d[1] = c;
      case 1:           d[0] = c;
      case 0:           /* do nothing */;
      }
      return orgd;
}

/* Set 'sz' 'int's beginning at 'd' to the value 'c' */
/* Returns address of block.  Does nothing if 'sz' equals zero */

void **msetP(void **d, void *c, int sz)
{
      void  **orgd = d;

      while (sz >= 16) {
            d[0] = c;
            d[1] = c;
            d[2] = c;
            d[3] = c;
            d[4] = c;
            d[5] = c;
            d[6] = c;
            d[7] = c;
            d[8] = c;
            d[9] = c;
            d[10] = c;
            d[11] = c;
            d[12] = c;
            d[13] = c;
            d[14] = c;
            d[15] = c;
            d += 16;
            sz -= 16;
      }
      switch (sz) {
      case 15:    d[14] = c;
      case 14:    d[13] = c;
      case 13:    d[12] = c;
      case 12:    d[11] = c;
      case 11:    d[10] = c;
      case 10:    d[9] = c;
      case 9:           d[8] = c;
      case 8:           d[7] = c;
      case 7:           d[6] = c;
      case 6:           d[5] = c;
      case 5:           d[4] = c;
      case 4:           d[3] = c;
      case 3:           d[2] = c;
      case 2:           d[1] = c;
      case 1:           d[0] = c;
      case 0:           /* do nothing */;
      }
      return orgd;
}

/* Set 'sz' 'char's beginning at 'd' to the value 'c' */
/* Returns address of block.  Does nothing if 'sz' equals zero */

unsigned char *mset(void *dest, unsigned char c, int sz)
{
      unsigned char     *d = dest;
      unsigned char     *orgd = dest;

      if (sz < 16) {
            switch (sz) {
            case 15:    d[14] = c;
            case 14:    d[13] = c;
            case 13:    d[12] = c;
            case 12:    d[11] = c;
            case 11:    d[10] = c;
            case 10:    d[9] = c;
            case 9:           d[8] = c;
            case 8:           d[7] = c;
            case 7:           d[6] = c;
            case 6:           d[5] = c;
            case 5:           d[4] = c;
            case 4:           d[3] = c;
            case 3:           d[2] = c;
            case 2:           d[1] = c;
            case 1:           d[0] = c;
            case 0:           /* do nothing */;
            }
      } else {
            unsigned z = SIZEOF_INT - ((unsigned long)d & (SIZEOF_INT - 1));

            if (z != SIZEOF_INT) {
                  switch (z) {
                  case 7:           d[6] = c;
                  case 6:           d[5] = c;
                  case 5:           d[4] = c;
                  case 4:           d[3] = c;
                  case 3:           d[2] = c;
                  case 2:           d[1] = c;
                  case 1:           d[0] = c;
                  case 0:           /* do nothing */;
                  }
                  d += z;
                  sz -= z;
            }
            msetI(d,
#if SIZEOF_INT >= 8
                  (c << (BITS * 7)) + (c << (BITS * 6)) + (c << (BITS * 5)) + (c << (BITS * 4)) +
#endif
#if SIZEOF_INT >= 4
                  (c << (BITS * 3)) + (c << (BITS * 2)) +
#endif
#if SIZEOF_INT >= 2
                  (c << BITS) +
#endif
                  c, sz >> SHFT);
            d += sz & ~(SIZEOF_INT - 1);
            switch (sz & (SIZEOF_INT - 1)) {
            case 7:           d[6] = c;
            case 6:           d[5] = c;
            case 5:           d[4] = c;
            case 4:           d[3] = c;
            case 3:           d[2] = c;
            case 2:           d[1] = c;
            case 1:           d[0] = c;
            case 0:           /* do nothing */;
            }
      }
      return orgd;
}

/* Copy a block of integers */
/* Copy from highest address to lowest */

static int *mbkwdI(void *dest, void *src, int sz)
{
      int   *d = dest;
      int   *s = src;

      if (d == s)
            return d;
      d += sz;
      s += sz;
      while (sz >= 16) {
            d -= 16;
            s -= 16;
            d[15] = s[15];
            d[14] = s[14];
            d[13] = s[13];
            d[12] = s[12];
            d[11] = s[11];
            d[10] = s[10];
            d[9] = s[9];
            d[8] = s[8];
            d[7] = s[7];
            d[6] = s[6];
            d[5] = s[5];
            d[4] = s[4];
            d[3] = s[3];
            d[2] = s[2];
            d[1] = s[1];
            d[0] = s[0];
            sz -= 16;
      }
      d -= sz;
      s -= sz;
      switch (sz) {
      case 15:    d[14] = s[14];
      case 14:    d[13] = s[13];
      case 13:    d[12] = s[12];
      case 12:    d[11] = s[11];
      case 11:    d[10] = s[10];
      case 10:    d[9] = s[9];
      case 9:           d[8] = s[8];
      case 8:           d[7] = s[7];
      case 7:           d[6] = s[6];
      case 6:           d[5] = s[5];
      case 5:           d[4] = s[4];
      case 4:           d[3] = s[3];
      case 3:           d[2] = s[2];
      case 2:           d[1] = s[1];
      case 1:           d[0] = s[0];
      case 0:           /* do nothing */;
      }
      return d;
}

/* Copy a block of 'int's.  Copy from lowest address to highest */

static int *mfwrdI(void *dest, void *src, int sz)
{
      int   *d = dest;
      int   *s = src;
      int   *od = d;

      if (s == d)
            return d;
      while (sz >= 16) {
            d[0] = s[0];
            d[1] = s[1];
            d[2] = s[2];
            d[3] = s[3];
            d[4] = s[4];
            d[5] = s[5];
            d[6] = s[6];
            d[7] = s[7];
            d[8] = s[8];
            d[9] = s[9];
            d[10] = s[10];
            d[11] = s[11];
            d[12] = s[12];
            d[13] = s[13];
            d[14] = s[14];
            d[15] = s[15];
            s += 16;
            d += 16;
            sz -= 16;
      }
      s -= 15 - sz;
      d -= 15 - sz;
      switch (sz) {
      case 15:    d[0] = s[0];
      case 14:    d[1] = s[1];
      case 13:    d[2] = s[2];
      case 12:    d[3] = s[3];
      case 11:    d[4] = s[4];
      case 10:    d[5] = s[5];
      case 9:           d[6] = s[6];
      case 8:           d[7] = s[7];
      case 7:           d[8] = s[8];
      case 6:           d[9] = s[9];
      case 5:           d[10] = s[10];
      case 4:           d[11] = s[11];
      case 3:           d[12] = s[12];
      case 2:           d[13] = s[13];
      case 1:           d[14] = s[14];
      case 0:           /* do nothing */;
      }
      return od;
}

/* Copy the block of 'sz' bytes beginning at 's' to 'd'.  If 'sz' is zero or
 * if 's'=='d', nothing happens.  The bytes at the highest address ('s'+'sz'-1)
 * are copied before the ones at the lowest ('s') are.
 */

static unsigned char *mbkwd(register unsigned char *d, register unsigned char *s, register int sz)
{
      if (s == d)
            return d;
      s += sz;
      d += sz;
#ifdef ALIGNED
      if (sz >= 16)
#else
      if (((unsigned long)s & (SIZEOF_INT - 1)) == ((unsigned long)d & (SIZEOF_INT - 1)) && sz >= 16)
#endif
      {
            unsigned z = ((unsigned long) s & (SIZEOF_INT - 1));

            s -= z;
            d -= z;
            switch (z) {
            case 7:           d[6] = s[6];
            case 6:           d[5] = s[5];
            case 5:           d[4] = s[4];
            case 4:           d[3] = s[3];
            case 3:           d[2] = s[2];
            case 2:           d[1] = s[1];
            case 1:           d[0] = s[0];
            case 0:           /* do nothing */;
            }
            sz -= z;
            mbkwdI(d - (sz & ~(SIZEOF_INT - 1)), s - (sz & ~(SIZEOF_INT - 1)), sz >> SHFT);
            d -= sz;
            s -= sz;
            switch (sz & (SIZEOF_INT - 1)) {
            case 7:           d[6] = s[6];
            case 6:           d[5] = s[5];
            case 5:           d[4] = s[4];
            case 4:           d[3] = s[3];
            case 3:           d[2] = s[2];
            case 2:           d[1] = s[1];
            case 1:           d[0] = s[0];
            case 0:           /* do nothing */;
            }
      } else {
            while (sz >= 16) {
                  d -= 16;
                  s -= 16;
                  d[15] = s[15];
                  d[14] = s[14];
                  d[13] = s[13];
                  d[12] = s[12];
                  d[11] = s[11];
                  d[10] = s[10];
                  d[9] = s[9];
                  d[8] = s[8];
                  d[7] = s[7];
                  d[6] = s[6];
                  d[5] = s[5];
                  d[4] = s[4];
                  d[3] = s[3];
                  d[2] = s[2];
                  d[1] = s[1];
                  d[0] = s[0];
                  sz -= 16;
            }
            d -= sz;
            s -= sz;
            switch (sz) {
            case 15:    d[14] = s[14];
            case 14:    d[13] = s[13];
            case 13:    d[12] = s[12];
            case 12:    d[11] = s[11];
            case 11:    d[10] = s[10];
            case 10:    d[9] = s[9];
            case 9:           d[8] = s[8];
            case 8:           d[7] = s[7];
            case 7:           d[6] = s[6];
            case 6:           d[5] = s[5];
            case 5:           d[4] = s[4];
            case 4:           d[3] = s[3];
            case 3:           d[2] = s[2];
            case 2:           d[1] = s[1];
            case 1:           d[0] = s[0];
            case 0:           /* do nothing */;
            }
      }
      return d;
}

/* Copy the block of 'sz' bytes beginning at 's' to 'd'.  If 'sz' is zero or
 * if 's'=='d', nothing happens.  The bytes at the lowest address ('s')
 * are copied before the ones at the highest ('s'+'sz'-1) are.
 */

static unsigned char *mfwrd(register unsigned char *d, register unsigned char *s, register int sz)
{
      unsigned char *od = d;

      if (d == s)
            return d;
#ifdef ALIGNED
      if (sz >= 16)
#else
      if (((unsigned long)d & (SIZEOF_INT - 1)) == ((unsigned long)s & (SIZEOF_INT - 1)) && sz >= 16)
#endif
      {
            unsigned z = ((unsigned long)s & (SIZEOF_INT - 1));

            if (z) {
                  s -= z;
                  d -= z;
                  switch (SIZEOF_INT - z) {
#if SIZEOF_INT == 8
                  case 7:           d[1] = s[1];
                  case 6:           d[2] = s[2];
                  case 5:           d[3] = s[3];
                  case 4:           d[4] = s[4];
                  case 3:           d[5] = s[5];
                  case 2:           d[6] = s[6];
                  case 1:           d[7] = s[7];
                  case 0:           /* do nothing */;
#else
#if SIZEOF_INT == 4
                  case 3:           d[1] = s[1];
                  case 2:           d[2] = s[2];
                  case 1:           d[3] = s[3];
                  case 0:           /* do nothing */;
#else
#if SIZEOF_INT == 2
                  case 1:           d[1] = s[1];
                  case 0:           /* do nothing */;
#endif
#endif
#endif
                  }
                  s += SIZEOF_INT;
                  d += SIZEOF_INT;
                  sz -= SIZEOF_INT - z;
            }
            mfwrdI(d, s, sz >> SHFT);
            s += sz - (SIZEOF_INT - 1);
            d += sz - (SIZEOF_INT - 1);
            switch (sz & (SIZEOF_INT - 1)) {
#if SIZEOF_INT == 8
            case 7:           d[0] = s[0];
            case 6:           d[1] = s[1];
            case 5:           d[2] = s[2];
            case 4:           d[3] = s[3];
            case 3:           d[4] = s[4];
            case 2:           d[5] = s[5];
            case 1:           d[6] = s[6];
            case 0:           /* do nothing */;
#else
#if SIZEOF_INT == 4
            case 3:           d[0] = s[0];
            case 2:           d[1] = s[1];
            case 1:           d[2] = s[2];
            case 0:           /* do nothing */;
#else
#if SIZEOF_INT == 2
            case 1:           d[0] = s[0];
            case 0:           /* do nothing */;
#endif
#endif
#endif
            }
      } else {
            while (sz >= 16) {
                  d[0] = s[0];
                  d[1] = s[1];
                  d[2] = s[2];
                  d[3] = s[3];
                  d[4] = s[4];
                  d[5] = s[5];
                  d[6] = s[6];
                  d[7] = s[7];
                  d[8] = s[8];
                  d[9] = s[9];
                  d[10] = s[10];
                  d[11] = s[11];
                  d[12] = s[12];
                  d[13] = s[13];
                  d[14] = s[14];
                  d[15] = s[15];
                  s += 16;
                  d += 16;
                  sz -= 16;
            }
            s -= 15 - sz;
            d -= 15 - sz;
            switch (sz) {
            case 15:    d[0] = s[0];
            case 14:    d[1] = s[1];
            case 13:    d[2] = s[2];
            case 12:    d[3] = s[3];
            case 11:    d[4] = s[4];
            case 10:    d[5] = s[5];
            case 9:           d[6] = s[6];
            case 8:           d[7] = s[7];
            case 7:           d[8] = s[8];
            case 6:           d[9] = s[9];
            case 5:           d[10] = s[10];
            case 4:           d[11] = s[11];
            case 3:           d[12] = s[12];
            case 2:           d[13] = s[13];
            case 1:           d[14] = s[14];
            case 0:           /* do nothing */;
            }
      }
      return od;
}

void *mmove(void *d, void *s, int sz)
{
      if (d > s)
            mbkwd(d, s, sz);
      else
            mfwrd(d, s, sz);
      return d;
}

/* Utility to count number of lines within a segment */

int mcnt(register unsigned char *blk, register unsigned char c, int size)
{
      register int nlines = 0;

      while (size >= 16) {
            if (blk[0] == c) ++nlines;
            if (blk[1] == c) ++nlines;
            if (blk[2] == c) ++nlines;
            if (blk[3] == c) ++nlines;
            if (blk[4] == c) ++nlines;
            if (blk[5] == c) ++nlines;
            if (blk[6] == c) ++nlines;
            if (blk[7] == c) ++nlines;
            if (blk[8] == c) ++nlines;
            if (blk[9] == c) ++nlines;
            if (blk[10] == c) ++nlines;
            if (blk[11] == c) ++nlines;
            if (blk[12] == c) ++nlines;
            if (blk[13] == c) ++nlines;
            if (blk[14] == c) ++nlines;
            if (blk[15] == c) ++nlines;
            blk += 16;
            size -= 16;
      }
      switch (size) {
      case 15:    if (blk[14] == c) ++nlines;
      case 14:    if (blk[13] == c) ++nlines;
      case 13:    if (blk[12] == c) ++nlines;
      case 12:    if (blk[11] == c) ++nlines;
      case 11:    if (blk[10] == c) ++nlines;
      case 10:    if (blk[9] == c) ++nlines;
      case 9:           if (blk[8] == c) ++nlines;
      case 8:           if (blk[7] == c) ++nlines;
      case 7:           if (blk[6] == c) ++nlines;
      case 6:           if (blk[5] == c) ++nlines;
      case 5:           if (blk[4] == c) ++nlines;
      case 4:           if (blk[3] == c) ++nlines;
      case 3:           if (blk[2] == c) ++nlines;
      case 2:           if (blk[1] == c) ++nlines;
      case 1:           if (blk[0] == c) ++nlines;
      case 0:           /* do nothing */;
      }
      return nlines;
}

#ifdef junk

unsigned char *mchr(blk, c)
register unsigned char *blk, c;
{
    loop:
      if (blk[0] == c) return blk + 0;
      if (blk[1] == c) return blk + 1;
      if (blk[2] == c) return blk + 2;
      if (blk[3] == c) return blk + 3;
      if (blk[4] == c) return blk + 4;
      if (blk[5] == c) return blk + 5;
      if (blk[6] == c) return blk + 6;
      if (blk[7] == c) return blk + 7;
      if (blk[8] == c) return blk + 8;
      if (blk[9] == c) return blk + 9;
      if (blk[10] == c) return blk + 10;
      if (blk[11] == c) return blk + 11;
      if (blk[12] == c) return blk + 12;
      if (blk[13] == c) return blk + 13;
      if (blk[14] == c) return blk + 14;
      if (blk[15] == c) return blk + 15;
      blk += 15;
      goto loop;
}

#endif

Generated by  Doxygen 1.6.0   Back to index