dbm/
misc/
old-docs/
/* case.c */

#include "copyright.h"
#include "config.h"

#include <sys/types.h>
#ifdef NEED_U_CHAR
typedef unsigned char u_char;
#endif				/* NEED_U_CHAR */

/*
 * This source file contains non-case sensitive string functions, based upon
 * Berkeley copyrighted material.  The start and end of the Berkeley material
 * is clearly marked.
 * 
 * Start of Berkeley include.
 */


/*
 * Copyright (c) 1987 Regents of the University of California. All rights
 * reserved.
 * 
 * Redistribution and use in source and binary forms are permitted provided that
 * this notice is preserved and that due credit is given to the University of
 * California at Berkeley. The name of the University may not be used to
 * endorse or promote products derived from this software without specific
 * written prior permission. This software is provided ``as is'' without
 * express or implied warranty.
 */

/*
 * This array is designed for mapping upper and lower case letters together
 * for a case independent comparison.  The mappings are based upon ascii
 * character sequences.
 */
static u_char   charmap[] = {
  '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
  '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377'
};

#ifdef NEED_STRCASECMP

int             strcasecmp(s1, s2)
  char           *s1, *s2;
{
  register u_char *cm = charmap, *us1 = (u_char *) s1, *us2 = (u_char *) s2;

  while (cm[*us1] == cm[*us2++])
    if (*us1++ == '\0')
      return (0);
  return (cm[*us1] - cm[*--us2]);
}

#endif				/* NEED_STRCASECMP */

#ifdef NEED_STRNCASECMP
int             strncasecmp(s1, s2, n)
  char           *s1, *s2;
  register int    n;
{
  register u_char *cm = charmap, *us1 = (u_char *) s1, *us2 = (u_char *) s2;

  while (--n >= 0 && cm[*us1] == cm[*us2++])
    if (*us1++ == '\0')
      return (0);
  return (n < 0 ? 0 : cm[*us1] - cm[*--us2]);
}

#endif				/* NEED_STRNCASECMP */

/*
 * End of Berkeley include.
 */


/* Returns non-NULL if one string is contained within the other. */

char           *
                strstr_CI(str, key)
  register char  *str;
  register char  *key;
{
  register u_char *cm = charmap;
  register u_char *curr = (u_char *) key;
  register u_char *holder = (u_char *) str;
  register u_char *ustr = (u_char *) str;

  while (ustr && *ustr && *curr) {
    if (cm[*ustr] == cm[*curr])
      curr++;
    else {
      curr = (u_char *) key;
      holder = (u_char *) str + 1;
    }
    ustr++;
  }

  if (*curr == '\0')
    return ((char *) holder);
  else
    return ((char *) 0);
}

/*
 * The following two arrays are used for fast upper and lower case
 * conversions. To use them, include "case.h", and use the macro DOWNCASE(x)
 * to convert to lowercase, or UPCASE(x) to convert to uppercase.
 * 
 * [Arrays Copyright(C) 1990 Robert Earl]
 */

static char     _lowercase[] = {
  -128, -127, -126, -125, -124, -123, -122, -121,
  -120, -119, -118, -117, -116, -115, -114, -113,
  -112, -111, -110, -109, -108, -107, -106, -105,
  -104, -103, -102, -101, -100, -99, -98, -97,
  -96, -95, -94, -93, -92, -91, -90, -89,
  -88, -87, -86, -85, -84, -83, -82, -81,
  -80, -79, -78, -77, -76, -75, -74, -73,
  -72, -71, -70, -69, -68, -67, -66, -65,
  -64, -63, -62, -61, -60, -59, -58, -57,
  -56, -55, -54, -53, -52, -51, -50, -49,
  -48, -47, -46, -45, -44, -43, -42, -41,
  -40, -39, -38, -37, -36, -35, -34, -33,
  -32, -31, -30, -29, -28, -27, -26, -25,
  -24, -23, -22, -21, -20, -19, -18, -17,
  -16, -15, -14, -13, -12, -11, -10, -9,
  -8, -7, -6, -5, -4, -3, -2, -1,
  0, 1, 2, 3, 4, 5, 6, 7,
  8, 9, 10, 11, 12, 13, 14, 15,
  16, 17, 18, 19, 20, 21, 22, 23,
  24, 25, 26, 27, 28, 29, 30, 31,
  32, 33, 34, 35, 36, 37, 38, 39,
  40, 41, 42, 43, 44, 45, 46, 47,
  48, 49, 50, 51, 52, 53, 54, 55,
  56, 57, 58, 59, 60, 61, 62, 63,
  64, 97, 98, 99, 100, 101, 102, 103,
  104, 105, 106, 107, 108, 109, 110, 111,
  112, 113, 114, 115, 116, 117, 118, 119,
  120, 121, 122, 91, 92, 93, 94, 95,
  96, 97, 98, 99, 100, 101, 102, 103,
  104, 105, 106, 107, 108, 109, 110, 111,
  112, 113, 114, 115, 116, 117, 118, 119,
  120, 121, 122, 123, 124, 125, 126, 127,
  128, 129, 130, 131, 132, 133, 134, 135,
  136, 137, 138, 139, 140, 141, 142, 143,
  144, 145, 146, 147, 148, 149, 150, 151,
  152, 153, 154, 155, 156, 157, 158, 159,
  160, 161, 162, 163, 164, 165, 166, 167,
  168, 169, 170, 171, 172, 173, 174, 175,
  176, 177, 178, 179, 180, 181, 182, 183,
  184, 185, 186, 187, 188, 189, 190, 191,
  192, 193, 194, 195, 196, 197, 198, 199,
  200, 201, 202, 203, 204, 205, 206, 207,
  208, 209, 210, 211, 212, 213, 214, 215,
  216, 217, 218, 219, 220, 221, 222, 223,
  224, 225, 226, 227, 228, 229, 230, 231,
  232, 233, 234, 235, 236, 237, 238, 239,
  240, 241, 242, 243, 244, 245, 246, 247,
  248, 249, 250, 251, 252, 253, 254, 255,
};

static char     _uppercase[] = {
  -128, -127, -126, -125, -124, -123, -122, -121,
  -120, -119, -118, -117, -116, -115, -114, -113,
  -112, -111, -110, -109, -108, -107, -106, -105,
  -104, -103, -102, -101, -100, -99, -98, -97,
  -96, -95, -94, -93, -92, -91, -90, -89,
  -88, -87, -86, -85, -84, -83, -82, -81,
  -80, -79, -78, -77, -76, -75, -74, -73,
  -72, -71, -70, -69, -68, -67, -66, -65,
  -64, -63, -62, -61, -60, -59, -58, -57,
  -56, -55, -54, -53, -52, -51, -50, -49,
  -48, -47, -46, -45, -44, -43, -42, -41,
  -40, -39, -38, -37, -36, -35, -34, -33,
  -32, -31, -30, -29, -28, -27, -26, -25,
  -24, -23, -22, -21, -20, -19, -18, -17,
  -16, -15, -14, -13, -12, -11, -10, -9,
  -8, -7, -6, -5, -4, -3, -2, -1,
  0, 1, 2, 3, 4, 5, 6, 7,
  8, 9, 10, 11, 12, 13, 14, 15,
  16, 17, 18, 19, 20, 21, 22, 23,
  24, 25, 26, 27, 28, 29, 30, 31,
  32, 33, 34, 35, 36, 37, 38, 39,
  40, 41, 42, 43, 44, 45, 46, 47,
  48, 49, 50, 51, 52, 53, 54, 55,
  56, 57, 58, 59, 60, 61, 62, 63,
  64, 65, 66, 67, 68, 69, 70, 71,
  72, 73, 74, 75, 76, 77, 78, 79,
  80, 81, 82, 83, 84, 85, 86, 87,
  88, 89, 90, 91, 92, 93, 94, 95,
  96, 65, 66, 67, 68, 69, 70, 71,
  72, 73, 74, 75, 76, 77, 78, 79,
  80, 81, 82, 83, 84, 85, 86, 87,
  88, 89, 90, 123, 124, 125, 126, 127,
  128, 129, 130, 131, 132, 133, 134, 135,
  136, 137, 138, 139, 140, 141, 142, 143,
  144, 145, 146, 147, 148, 149, 150, 151,
  152, 153, 154, 155, 156, 157, 158, 159,
  160, 161, 162, 163, 164, 165, 166, 167,
  168, 169, 170, 171, 172, 173, 174, 175,
  176, 177, 178, 179, 180, 181, 182, 183,
  184, 185, 186, 187, 188, 189, 190, 191,
  192, 193, 194, 195, 196, 197, 198, 199,
  200, 201, 202, 203, 204, 205, 206, 207,
  208, 209, 210, 211, 212, 213, 214, 215,
  216, 217, 218, 219, 220, 221, 222, 223,
  224, 225, 226, 227, 228, 229, 230, 231,
  232, 233, 234, 235, 236, 237, 238, 239,
  240, 241, 242, 243, 244, 245, 246, 247,
  248, 249, 250, 251, 252, 253, 254, 255,
};

char           *lowercase = _lowercase + 128;
char           *uppercase = _uppercase + 128;

/*
 * End of code by Robert Earl.
 */

int             stringprefix(pref, str)
  register char  *pref;
  register char  *str;
{
  while (*pref && *str && (lowercase[*pref] == lowercase[*str])) {
    pref++;
    str++;
  }
  return (*pref == '\0');
}