utils.c

来自「举世闻名的joe记事本源程序」· C语言 代码 · 共 663 行

C
663
字号
/* *	Various utilities *	Copyright *		(C) 1992 Joseph H. Allen *		(C) 2001 Marek 'Marx' Grac * *	This file is part of JOE (Joe's Own Editor) */#include "types.h"#if 0int joe_ispunct(int wide,struct charmap *map,int c){	if (joe_isspace(c))		return 0;	if (c=='_')		return 1;	if (isalnum_(wide,map,c))		return 0;	return joe_isprint(wide,map,c);}#endif/* * return minimum/maximum of two numbers */unsigned int uns_min(unsigned int a, unsigned int b){	return a < b ? a : b;}signed int int_min(signed int a, signed int b){	return a < b ? a : b;}signed long int long_max(signed long int a, signed long int b){	return a > b ? a : b;}signed long int long_min(signed long int a, signed long int b){	return a < b ? a : b;}#if 0/*  * Characters which are considered as word characters  * 	_ is considered as word character because is often used  *	in the names of C/C++ functions */int isalnum_(int wide,struct charmap *map,int c){	/* Fast... */	if (c>='0' && c<='9' ||	    c>='a' && c<='z' ||	    c>='A' && c<='Z' ||	    c=='_')	  return 1;	else if(c<128)	  return 0;	/* Slow... */	if (wide)		return joe_iswalpha(c);	else		return joe_iswalpha(to_uni(map,c));}int isalpha_(int wide,struct charmap *map,int c){	/* Fast... */	if (c>='a' && c<='z' ||	    c>='A' && c<='Z' ||	    c=='_')	  return 1;	else if(c<128)	  return 0;	/* Slow... */	if (wide)		return joe_iswalpha(c);	else		return joe_iswalpha(to_uni(map,c));}#endif/* Versions of 'read' and 'write' which automatically retry when interrupted */ssize_t joe_read(int fd, void *buf, size_t size){	ssize_t rt;	do {		rt = read(fd, buf, size);	} while (rt < 0 && errno == EINTR);	return rt;}ssize_t joe_write(int fd, void *buf, size_t size){	ssize_t rt;	do {		rt = write(fd, buf, size);	} while (rt < 0 && errno == EINTR);	return rt;}/* Heap checking versions of malloc() *//* #define HEAP_CHECK 1 */#ifdef HEAP_CHECKstruct mcheck {	struct mcheck *next;	int state;		/* 0=malloced, 1=free */	int size;		/* size in bytes */	int magic;};struct mcheck *first;struct mcheck *last;void check_malloc(){	struct mcheck *m;	int y = 0;	for(m=first;m;m=m->next) {		unsigned char *ptr = (unsigned char *)m+sizeof(struct mcheck);		int x;		if(m->magic!=0x55AA55AA) {			printf("corrupt heap: head %x\n",ptr);			*(int *)0=0;		}		for(x=0;x!=16384;++x)			if(ptr[x+m->size]!=0xAA) {				printf("Corrupt heap: tail %x\n",ptr);				*(int *)0=0;			}		if(m->state)			for(x=0;x!=m->size;++x)				if(ptr[x]!=0x41) {					printf("Corrupt heap: modified free block %x\n",ptr);					*(int *)0=0;				}		++y;	}}void *joe_malloc(size_t size){	struct mcheck *m = (struct mcheck *)malloc(size+sizeof(struct mcheck)+16384);	unsigned char *ptr = (unsigned char *)m+sizeof(struct mcheck);	int x;	m->state = 0;	m->size = size;	m->magic=0x55AA55AA;	m->next = 0;	if(!size) {		printf("0 passed to malloc\n");		*(int *)0=0;	}	for(x=0;x!=16384;++x)		ptr[x+size]=0xAA;	if(first) {		last->next = m;		last = m;	} else {		first = last = m;	}	check_malloc();	/* printf("malloc size=%d addr=%x\n",size,ptr); fflush(stdout); */	return ptr;}void *joe_calloc(size_t nmemb, size_t size){	size_t sz = nmemb*size;	int x;	unsigned char *ptr;	ptr = joe_malloc(sz);	for(x=0;x!=sz;++x)		ptr[x] = 0;	return ptr;}void *joe_realloc(void *ptr, size_t size){	struct mcheck *n;	unsigned char *np;	struct mcheck *m = (struct mcheck *)((char *)ptr-sizeof(struct mcheck));	if(!size) {		printf("0 passed to realloc\n");		*(int *)0=0;	}	np = joe_malloc(size);	n = (struct mcheck *)(np-sizeof(struct mcheck));	if(m->size>size)		memcpy(np,ptr,size);	else		memcpy(np,ptr,m->size);	joe_free(ptr);	return np;}void joe_free(void *ptr){	struct mcheck *m = (struct mcheck *)((char *)ptr-sizeof(struct mcheck));	int x;	if (m->magic!=0x55AA55AA) {		printf("Free non-malloc block %x\n",ptr);		*(int *)0=0x0;	}	if (m->state) {		printf("Double-free %x\n",ptr);		*(int *)0=0x0;	}	for(x=0;x!=m->size;++x)		((unsigned char *)ptr)[x]=0x41;	m->state = 1;	check_malloc();	/* printf("free=%x\n",ptr); */}#else/* Normal malloc() */void *joe_malloc(size_t size){	return malloc(size);}void *joe_calloc(size_t nmemb,size_t size){	return calloc(nmemb,size);}void *joe_realloc(void *ptr,size_t size){	return realloc(ptr,size);}void joe_free(void *ptr){	free(ptr);}#endifsize_t zlen(unsigned char *s){	return strlen((char *)s);}int zcmp(unsigned char *a, unsigned char *b){	return strcmp((char *)a, (char *)b);}int zncmp(unsigned char *a, unsigned char *b, size_t len){	return strncmp((char *)a, (char *)b, len);}unsigned char *zdup(unsigned char *bf){	int size = zlen(bf);	unsigned char *p = (unsigned char *)joe_malloc(size+1);	memcpy(p,bf,size+1);	return p;}unsigned char *zcpy(unsigned char *a, unsigned char *b){	strcpy((char *)a,(char *)b);	return a;}unsigned char *zstr(unsigned char *a, unsigned char *b){	return (unsigned char *)strstr((char *)a,(char *)b);}unsigned char *zncpy(unsigned char *a, unsigned char *b, size_t len){	strncpy((char *)a,(char *)b,len);	return a;}unsigned char *zcat(unsigned char *a, unsigned char *b){	strcat((char *)a,(char *)b);	return a;}unsigned char *zchr(unsigned char *s, int c){	return (unsigned char *)strchr((char *)s,c);}unsigned char *zrchr(unsigned char *s, int c){	return (unsigned char *)strrchr((char *)s,c);}#ifdef junkvoid *replenish(void **list,int size){	unsigned char *i = joe_malloc(size*16);	int x;	for (x=0; x!=15; ++x) {		fr_single(list, i);		i += size;	}	return i;}/* Destructors */GC *gc_free_list = 0;void gc_add(GC **gc, void **var, void (*rm)(void *val)){	GC *g;	for (g = *gc; g; g=g->next)		if (g->var == var)			return;	g = al_single(&gc_free_list, GC);	g = gc_free_list;	gc_free_list = g->next;	g->next = *gc;	*gc = g;	g->var = var;	g->rm = rm;}void gc_collect(GC **gc){	GC *g = *gc;	while (g) {		GC *next = g->next;		if (*g->var) {			g->rm(*g->var);			*g->var = 0;		}		fr_single(&gc_free_list,g);		g = next;	}	*gc = 0;}#endif/* Zstrings */void rm_zs(ZS z){	joe_free(z.s);}ZS raw_mk_zs(GC **gc,unsigned char *s,int len){	ZS zs;	zs.s = (unsigned char *)joe_malloc(len+1);	if (len)		memcpy(zs.s,s,len);	zs.s[len] = 0;	return zs;}#ifndef SIG_ERR#define SIG_ERR ((sighandler_t) -1)#endif/* wrapper to hide signal interface differrencies */int joe_set_signal(int signum, sighandler_t handler){	int retval;#ifdef HAVE_SIGACTION	struct sigaction sact;	mset(&sact, 0, sizeof(sact));	sact.sa_handler = handler;#ifdef SA_INTERRUPT	sact.sa_flags = SA_INTERRUPT;#endif	retval = sigaction(signum, &sact, NULL);#elif defined(HAVE_SIGVEC)	struct sigvec svec;	mset(&svec, 0, sizeof(svec));	svec.sv_handler = handler;#ifdef HAVE_SV_INTERRUPT	svec.sv_flags = SV_INTERRUPT;#endif	retval = sigvec(signum, &svec, NULL);#else	retval = (signal(signum, handler) != SIG_ERR) ? 0 : -1;#ifdef HAVE_SIGINTERRUPT	siginterrupt(signum, 1);#endif#endif	return(retval);}/* Helpful little parsing utilities *//* Skip whitespace and return first non-whitespace character */int parse_ws(unsigned char **pp,int cmt){	unsigned char *p = *pp;	while (*p==' ' || *p=='\t')		++p;	if (*p=='\r' || *p=='\n' || *p==cmt)		*p = 0;	*pp = p;	return *p;}/* Parse an identifier into a buffer.  Identifier is truncated to a maximum of len-1 chars. */int parse_ident(unsigned char **pp, unsigned char *buf, int len){	unsigned char *p = *pp;	if (joe_isalpha_(locale_map,*p)) {		while(len > 1 && joe_isalnum_(locale_map,*p))			*buf++= *p++, --len;		*buf=0;		while(joe_isalnum_(locale_map,*p))			++p;		*pp = p;		return 0;	} else		return -1;}/* Parse to next whitespace */int parse_tows(unsigned char **pp, unsigned char *buf){	unsigned char *p = *pp;	while (*p && *p!=' ' && *p!='\t' && *p!='\n' && *p!='\r' && *p!='#')		*buf++ = *p++;	*pp = p;	*buf = 0;	return 0;}/* Parse over a specific keyword */int parse_kw(unsigned char **pp, unsigned char *kw){	unsigned char *p = *pp;	while(*kw && *kw==*p)		++kw, ++p;	if(!*kw && !joe_isalnum_(locale_map,*p)) {		*pp = p;		return 0;	} else		return -1;}/* Parse a field (same as parse_kw, but string must be terminated with whitespace) */int parse_field(unsigned char **pp, unsigned char *kw){	unsigned char *p = *pp;	while(*kw && *kw==*p)		++kw, ++p;	if(!*kw && (!*p || *p==' ' || *p=='\t' || *p=='#' || *p=='\n' || *p=='\r')) {		*pp = p;		return 0;	} else		return -1;}/* Parse a specific character */int parse_char(unsigned char **pp, unsigned char c){	unsigned char *p = *pp;	if (*p == c) {		*pp = p+1;		return 0;	} else		return -1;}/* Parse an integer.  Returns 0 for success. */int parse_int(unsigned char **pp, int *buf){	unsigned char *p = *pp;	if ((*p>='0' && *p<='9') || *p=='-') {		*buf = atoi((char *)p);		if(*p=='-')			++p;		while(*p>='0' && *p<='9')			++p;		*pp = p;		return 0;	} else		return -1;}/* Parse a long */int parse_long(unsigned char **pp, long *buf){	unsigned char *p = *pp;	if ((*p>='0' && *p<='9') || *p=='-') {		*buf = atol((char *)p);		if(*p=='-')			++p;		while(*p>='0' && *p<='9')			++p;		*pp = p;		return 0;	} else		return -1;}/* Parse a string of the form "xxxxx" into a fixed-length buffer.  The * address of the buffer is 'buf'.  The length of this buffer is 'len'.  A * terminating NUL is added to the parsed string.  If the string is larger * than the buffer, the string is truncated. * * C string escape sequences are handled. * * 'p' holds an address of the input string pointer.  The pointer * is updated to point right after the parsed string if the function * succeeds. * * Returns the length of the string (not including the added NUL), or * -1 if there is no string or if the input ended before the terminating ". */int parse_string(unsigned char **pp, unsigned char *buf, int len){	unsigned char *start = buf;	unsigned char *p= *pp;	if(*p=='\"') {		++p;		while(len > 1 && *p && *p!='\"') {			int x = 50;			int c = escape(0, &p, &x);			*buf++ = c;			--len;		}		*buf = 0;		while(*p && *p!='\"')			if(*p=='\\' && p[1])				p += 2;			else				p++;		if(*p == '\"') {			*pp = p + 1;			return buf - start;		}	}	return -1;}/* Emit a string with escape sequences */#ifdef junk/* Used originally for printing macros */void emit_string(FILE *f,unsigned char *s,int len){	unsigned char buf[8];	unsigned char *p, *q;	fputc('\"',f);	while(len) {		p = unescape(buf,*s++);		for(q=buf;q!=p;++q)			fputc(*q,f);		--len;	}	fputc('\"',f);}#endif/* Emit a string */void emit_string(FILE *f,unsigned char *s,int len){	fputc('"',f);	while(len) {		if (*s=='"' || *s=='\\')			fputc('\\',f), fputc(*s,f);		else if(*s=='\n')			fputc('\\',f), fputc('n',f);		else if(*s=='\r')			fputc('\\',f), fputc('r',f);		else if(*s==0)			fputc('\\',f), fputc('0',f), fputc('0',f), fputc('0',f);		else			fputc(*s,f);		++s;		--len;	}	fputc('"',f);}/* Parse a character range: a-z */int parse_range(unsigned char **pp, int *first, int *second){	unsigned char *p= *pp;	int a, b;	if(!*p)		return -1;	if(*p=='\\' && p[1]) {		++p;		if(*p=='n')			a = '\n';		else if(*p=='t')  			a = '\t';		else			a = *p;		++p;	} else		a = *p++;	if(*p=='-' && p[1]) {		++p;		if(*p=='\\' && p[1]) {			++p;			if(*p=='n')				b = '\n';			else if(*p=='t')				b = '\t';			else				b = *p;			++p;		} else			b = *p++;	} else		b = a;	*first = a;	*second = b;	*pp = p;	return 0;}

⌨️ 快捷键说明

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