⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc.c

📁 广泛使用的邮件服务器!同时
💻 C
字号:
/* ======================================================================== * Copyright 1988-2006 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * *  * ======================================================================== *//* * Program:	Miscellaneous utility routines * * Author:	Mark Crispin *		Networks and Distributed Computing *		Computing & Communications *		University of Washington *		Administration Building, AG-44 *		Seattle, WA  98195 *		Internet: MRC@CAC.Washington.EDU * * Date:	5 July 1988 * Last Edited:	6 December 2006 * * This original version of this file is * Copyright 1988 Stanford University * and was developed in the Symbolic Systems Resources Group of the Knowledge * Systems Laboratory at Stanford University in 1987-88, and was funded by the * Biomedical Research Technology Program of the NationalInstitutes of Health * under grant number RR-00785. */#include <ctype.h>#include "c-client.h"/* Convert ASCII string to all uppercase * Accepts: string pointer * Returns: string pointer * * Don't use islower/toupper since this function must be ASCII only. */unsigned char *ucase (unsigned char *s){  unsigned char *t;				/* if lowercase covert to upper */  for (t = s; *t; t++) if ((*t >= 'a') && (*t <= 'z')) *t -= ('a' - 'A');  return s;			/* return string */}/* Convert string to all lowercase * Accepts: string pointer * Returns: string pointer * * Don't use isupper/tolower since this function must be ASCII only. */unsigned char *lcase (unsigned char *s){  unsigned char *t;				/* if uppercase covert to lower */  for (t = s; *t; t++) if ((*t >= 'A') && (*t <= 'Z')) *t += ('a' - 'A');  return s;			/* return string */}/* Copy string to free storage * Accepts: source string * Returns: free storage copy of string */char *cpystr (const char *string){  return string ? strcpy ((char *) fs_get (1 + strlen (string)),string) : NIL;}/* Copy text/size to free storage as sized text * Accepts: destination sized text *	    pointer to source text *	    size of source text * Returns: text as a char * */char *cpytxt (SIZEDTEXT *dst,char *text,unsigned long size){				/* flush old space */  if (dst->data) fs_give ((void **) &dst->data);				/* copy data in sized text */  memcpy (dst->data = (unsigned char *)	  fs_get ((size_t) (dst->size = size) + 1),text,(size_t) size);  dst->data[size] = '\0';	/* tie off text */  return (char *) dst->data;	/* convenience return */}/* Copy sized text to free storage as sized text * Accepts: destination sized text *	    source sized text * Returns: text as a char * */char *textcpy (SIZEDTEXT *dst,SIZEDTEXT *src){				/* flush old space */  if (dst->data) fs_give ((void **) &dst->data);				/* copy data in sized text */  memcpy (dst->data = (unsigned char *)	  fs_get ((size_t) (dst->size = src->size) + 1),	  src->data,(size_t) src->size);  dst->data[dst->size] = '\0';	/* tie off text */  return (char *) dst->data;	/* convenience return */}/* Copy stringstruct to free storage as sized text * Accepts: destination sized text *	    source stringstruct * Returns: text as a char * */char *textcpystring (SIZEDTEXT *text,STRING *bs){  unsigned long i = 0;				/* clear old space */  if (text->data) fs_give ((void **) &text->data);				/* make free storage space in sized text */  text->data = (unsigned char *) fs_get ((size_t) (text->size = SIZE (bs)) +1);  while (i < text->size) text->data[i++] = SNX (bs);  text->data[i] = '\0';		/* tie off text */  return (char *) text->data;	/* convenience return */}/* Copy stringstruct from offset to free storage as sized text * Accepts: destination sized text *	    source stringstruct *	    offset into stringstruct *	    size of source text * Returns: text as a char * */char *textcpyoffstring (SIZEDTEXT *text,STRING *bs,unsigned long offset,			unsigned long size){  unsigned long i = 0;				/* clear old space */  if (text->data) fs_give ((void **) &text->data);  SETPOS (bs,offset);		/* offset the string */				/* make free storage space in sized text */  text->data = (unsigned char *) fs_get ((size_t) (text->size = size) + 1);  while (i < size) text->data[i++] = SNX (bs);  text->data[i] = '\0';		/* tie off text */  return (char *) text->data;	/* convenience return */}/* Returns index of rightmost bit in word * Accepts: pointer to a 32 bit value * Returns: -1 if word is 0, else index of rightmost bit * * Bit is cleared in the word */unsigned long find_rightmost_bit (unsigned long *valptr){  unsigned long value = *valptr;  unsigned long bit = 0;  if (!(value & 0xffffffff)) return 0xffffffff;				/* binary search for rightmost bit */  if (!(value & 0xffff)) value >>= 16, bit += 16;  if (!(value & 0xff)) value >>= 8, bit += 8;  if (!(value & 0xf)) value >>= 4, bit += 4;  if (!(value & 0x3)) value >>= 2, bit += 2;  if (!(value & 0x1)) value >>= 1, bit += 1;  *valptr ^= (1 << bit);	/* clear specified bit */  return bit;}/* Return minimum of two integers * Accepts: integer 1 *	    integer 2 * Returns: minimum */long min (long i,long j){  return ((i < j) ? i : j);}/* Return maximum of two integers * Accepts: integer 1 *	    integer 2 * Returns: maximum */long max (long i,long j){  return ((i > j) ? i : j);}/* Search, case-insensitive for ASCII characters * Accepts: base string *	    length of base string *	    pattern string *	    length of pattern string * Returns: T if pattern exists inside base, else NIL */long search (unsigned char *base,long basec,unsigned char *pat,long patc){  long i,j,k;  int c;  unsigned char mask[256];  static unsigned char alphatab[256] = {    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,    223,223,223,223,223,223,223,223,223,223,223,255,255,255,255,255,    255,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,    223,223,223,223,223,223,223,223,223,223,223,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255    };				/* validate arguments */  if (base && (basec > 0) && pat && (basec >= patc)) {    if (patc <= 0) return T;	/* empty pattern always succeeds */    memset (mask,0,256);	/* initialize search validity mask */    for (i = 0; i < patc; i++) if (!mask[c = pat[i]]) {				/* mark single character if non-alphabetic */      if (alphatab[c] & 0x20) mask[c] = T;				/* else mark both cases */      else mask[c & 0xdf] = mask[c | 0x20] = T;    }				/* Boyer-Moore type search */    for (i = --patc; i < basec; i += (mask[c] ? 1 : (j + 1)))      for (j = patc,c = base[k = i]; !((c ^ pat[j]) & alphatab[c]);	   j--,c = base[--k])	if (!j) return T;	/* found a match! */  }  return NIL;			/* pattern not found */}/* Boyer-Moore string search * Accepts: base string *	    length of base string *	    pattern string *	    length of pattern string * Returns: T if pattern exists inside base, else NIL */long ssearch (unsigned char *base,long basec,unsigned char *pat,long patc){  long i,j,k;  int c;  unsigned char mask[256];				/* validate arguments */  if (base && (basec > 0) && pat && (basec >= patc)) {    if (patc <= 0) return T;	/* empty pattern always succeeds */    memset (mask,0,256);	/* initialize search validity mask */    for (i = 0; i < patc; i++) mask[pat[i]] = T;				/* Boyer-Moore type search */    for (i = --patc, c = pat[i]; i < basec; i += (mask[c] ? 1 : (j + 1)))      for (j = patc,c = base[k = i]; (c == pat[j]); j--,c = base[--k])	if (!j) return T;	/* found a match! */  }  return NIL;			/* pattern not found */}/* Create a hash table * Accepts: size of new table (note: should be a prime) * Returns: hash table */HASHTAB *hash_create (size_t size){  size_t i = sizeof (size_t) + size * sizeof (HASHENT *);  HASHTAB *ret = (HASHTAB *) memset (fs_get (i),0,i);  ret->size = size;  return ret;}/* Destroy hash table * Accepts: hash table */void hash_destroy (HASHTAB **hashtab){  if (*hashtab) {    hash_reset (*hashtab);	/* reset hash table */    fs_give ((void **) hashtab);  }}/* Reset hash table * Accepts: hash table */void hash_reset (HASHTAB *hashtab){  size_t i;  HASHENT *ent,*nxt;				/* free each hash entry */  for (i = 0; i < hashtab->size; i++) if (ent = hashtab->table[i])    for (hashtab->table[i] = NIL; ent; ent = nxt) {      nxt = ent->next;		/* get successor */      fs_give ((void **) &ent);	/* flush this entry */    }}/* Calculate index into hash table * Accepts: hash table *	    entry name * Returns: index */unsigned long hash_index (HASHTAB *hashtab,char *key){  unsigned long i,ret;				/* polynomial of letters of the word */  for (ret = 0; i = (unsigned int) *key++; ret += i) ret *= HASHMULT;  return ret % (unsigned long) hashtab->size;}/* Look up name in hash table * Accepts: hash table *	    key * Returns: associated data */void **hash_lookup (HASHTAB *hashtab,char *key){  HASHENT *ret;  for (ret = hashtab->table[hash_index (hashtab,key)]; ret; ret = ret->next)    if (!strcmp (key,ret->name)) return ret->data;  return NIL;}/* Add entry to hash table * Accepts: hash table *	    key *	    associated data *	    number of extra data slots * Returns: hash entry * Caller is responsible for ensuring that entry isn't already in table */HASHENT *hash_add (HASHTAB *hashtab,char *key,void *data,long extra){  unsigned long i = hash_index (hashtab,key);  size_t j = sizeof (HASHENT) + (extra * sizeof (void *));  HASHENT *ret = (HASHENT *) memset (fs_get (j),0,j);  ret->next = hashtab->table[i];/* insert as new head in this index */  ret->name = key;		/* set up hash key */  ret->data[0] = data;		/* and first data */  return hashtab->table[i] = ret;}/* Look up name in hash table * Accepts: hash table *	    key *	    associated data *	    number of extra data slots * Returns: associated data */void **hash_lookup_and_add (HASHTAB *hashtab,char *key,void *data,long extra){  HASHENT *ret;  unsigned long i = hash_index (hashtab,key);  size_t j = sizeof (HASHENT) + (extra * sizeof (void *));  for (ret = hashtab->table[i]; ret; ret = ret->next)    if (!strcmp (key,ret->name)) return ret->data;  ret = (HASHENT *) memset (fs_get (j),0,j);  ret->next = hashtab->table[i];/* insert as new head in this index */  ret->name = key;		/* set up hash key */  ret->data[0] = data;		/* and first data */  return (hashtab->table[i] = ret)->data;}/* Convert two hex characters into byte * Accepts: char for high nybble *	    char for low nybble * Returns: byte * * Arguments must be isxdigit validated */unsigned char hex2byte (unsigned char c1,unsigned char c2){				/* merge the two nybbles */  return ((c1 -= (isdigit (c1) ? '0' : ((c1 <= 'Z') ? 'A' : 'a') - 10)) << 4) +    (c2 - (isdigit (c2) ? '0' : ((c2 <= 'Z') ? 'A' : 'a') - 10));}/* Compare two unsigned longs * Accepts: first value *	    second value * Returns: -1 if l1 < l2, 0 if l1 == l2, 1 if l1 > l2 */int compare_ulong (unsigned long l1,unsigned long l2){  if (l1 < l2) return -1;  if (l1 > l2) return 1;  return 0;}/* Compare two unsigned chars, case-independent * Accepts: first value *	    second value * Returns: -1 if c1 < c2, 0 if c1 == c2, 1 if c1 > c2 * * Don't use isupper/tolower since this function must be ASCII only. */int compare_uchar (unsigned char c1,unsigned char c2){  return compare_ulong (((c1 >= 'A') && (c1 <= 'Z')) ? c1 + ('a' - 'A') : c1,			((c2 >= 'A') && (c2 <= 'Z')) ? c2 + ('a' - 'A') : c2);}/* Compare two case-independent ASCII strings * Accepts: first string *	    second string * Returns: -1 if s1 < s2, 0 if s1 == s2, 1 if s1 > s2 */int compare_cstring (unsigned char *s1,unsigned char *s2){  int i;  if (!s1) return s2 ? -1 : 0;	/* empty string cases */  else if (!s2) return 1;  for (; *s1 && *s2; s1++,s2++) if (i = (compare_uchar (*s1,*s2))) return i;  if (*s1) return 1;		/* first string is longer */  return *s2 ? -1 : 0;		/* second string longer : strings identical */}/* Compare case-independent string with sized text * Accepts: first string *	    sized text * Returns: -1 if s1 < s2, 0 if s1 == s2, 1 if s1 > s2 */int compare_csizedtext (unsigned char *s1,SIZEDTEXT *s2){  int i;  unsigned char *s;  unsigned long j;  if (!s1) return s2 ? -1 : 0;	/* null string cases */  else if (!s2) return 1;  for (s = (char *) s2->data,j = s2->size; *s1 && j; ++s1,++s,--j)    if (i = (compare_uchar (*s1,*s))) return i;  if (*s1) return 1;		/* first string is longer */  return j ? -1 : 0;		/* second string longer : strings identical */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -