cdrtools/libschily/cmpmbytes.c

123 lines
2.6 KiB
C
Raw Normal View History

2025-06-15 04:19:58 +08:00
/* @(#)cmpmbytes.c 1.2 11/08/16 Copyright 1988, 1995-2011 J. Schilling */
#include <schily/mconfig.h>
#ifndef lint
static UConst char sccsid[] =
"@(#)cmpmbytes.c 1.2 11/08/16 Copyright 1988, 1995-2011 J. Schilling";
#endif
/*
* compare data
* Return the difference from the first differing characters
*
* Copyright (c) 1988, 1995-2011 J. Schilling
*/
/*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* See the file CDDL.Schily.txt in this distribution for details.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file CDDL.Schily.txt from this distribution.
*/
#include <schily/standard.h>
#include <schily/align.h>
#include <schily/types.h>
#include <schily/schily.h>
#define DO8(a) a; a; a; a; a; a; a; a;
/*
* Return the difference from the first differing characters
* This interface is compatible to memcmp()
*/
EXPORT int
cmpmbytes(fromp, top, cnt)
const void *fromp;
const void *top;
ssize_t cnt;
{
register const char *from = (char *)fromp;
register const char *to = (char *)top;
register ssize_t n;
register ssize_t i;
/*
* If we change cnt to be unsigned, check for == instead of <=
*/
if ((n = cnt) <= 0)
return (0);
/*
* Compare byte-wise until properly aligned for a long pointer.
*/
i = sizeof (long) - 1;
while (--n >= 0 && --i >= 0 && !l2aligned(from, to)) {
if (*to++ != *from++)
goto cdiff;
}
n++;
if (n >= (ssize_t)(8 * sizeof (long))) {
if (l2aligned(from, to)) {
register const long *froml = (const long *)from;
register const long *tol = (const long *)to;
register ssize_t rem = n % (8 * sizeof (long));
n /= (8 * sizeof (long));
do {
/* BEGIN CSTYLED */
DO8(
if (*tol++ != *froml++)
break;
);
/* END CSTYLED */
} while (--n > 0);
if (n > 0) {
--froml;
--tol;
to = (const char *)tol;
from = (const char *)froml;
goto ldiff;
}
to = (const char *)tol;
from = (const char *)froml;
n = rem;
}
if (n >= 8) {
n -= 8;
do {
/* BEGIN CSTYLED */
DO8(
if (*to++ != *from++)
goto cdiff;
);
/* END CSTYLED */
} while ((n -= 8) >= 0);
n += 8;
}
if (n > 0) do {
if (*to++ != *from++)
goto cdiff;
} while (--n > 0);
return (0);
}
if (n > 0) do {
if (*to++ != *from++)
goto cdiff;
} while (--n > 0);
return (0);
ldiff:
n = sizeof (long);
do {
if (*to++ != *from++)
goto cdiff;
} while (--n > 0);
cdiff:
return (*((unsigned char *)--from) - *((unsigned char *)--to));
}