misc.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,261 行 · 第 1/2 页
C
1,261 行
#ifndef lintstatic char *sccsid = "@(#)misc.c 4.2 (ULTRIX) 10/16/90";#endif lint/************************************************************************ * * * Copyright (c) 1986,1987,1988,1989 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * * Modification History: * * 14-Apr-89 Tim N. * Removed local vax conditional definition of calloc routine. * Also put in 3.1 fixes which were: * Changed the get routine to use null terminated * string copy to get proper end of string on * local copies of the file names passed in. Also added special * handling of the SHELL and MAKESHELL env vars while in POSIX mode. * */#include "defs"#include "ctype.h"CHARSTAR do_colon();CHARSTAR do_df();#if 0FSTATIC CHARSTAR nextchar=0;FSTATIC CHARSTAR lastchar=0;FSTATIC int *nextint=0;FSTATIC int *lastint=0;#endif 0int nhashed=0;/* simple linear hash. hash function is sum of characters mod hash table size.*/hashloc(s)register CHARSTAR s;{ register int i; register int hashval; register CHARSTAR t; hashval = 0; for(t=s; *t!=CNULL ; ++t) hashval += *t; hashval &= HASHSIZE; for(i=hashval; hashtab[i]!=0 && !equal(s,hashtab[i]->namep); i = (i+1)&HASHSIZE ) ; return(i);}/* made this a macro....rrNAMEBLOCKsrchname(s)register CHARSTAR s;{ return( hashtab[hashloc(s)] );}*/NAMEBLOCKmakename(s)register CHARSTAR s;{ /* make a name entry; `s' is presumed to already to have been saved */ register NAMEBLOCK p; if(nhashed++ > HASHSIZE-3) fatal("Hash table overflow"); p = ALLOC(nameblock); p->nextname = firstname; p->backname = NULL; p->namep = s; p->linep = 0; p->done = 0; p->septype = 0; p->rundep = 0; p->modtime = 0; firstname = p; hashtab[hashloc(s)] = p; return(p);}#define NOTSHORT sizeof (struct nameblock)#define TABLESIZE 127 /* must be 2**n -1 */#define TRUE 1#define FALSE 0CHARSTARcopys(s)register CHARSTAR s;{#ifdef SYSV register CHARSTAR t; static struct entry /* structure will form linked */ { /* list of strings in alpha-order. */ CHARSTAR name; /* table is hash-table of 100 els. */ struct entry *next; /* used to make searching faster. */ } *table[TABLESIZE],*laste,*newe,*e; register int found; register int i; register int hashval = 0; for(t=s; *t != CNULL; ++t) /* Hash the string - sum of chars */ hashval += *t; hashval &= TABLESIZE; /* Mod tablesize */ e = table[hashval]; /* initial element */ laste = table[hashval]; while(TRUE) if(e == NULL) /* No - table[hashval] == NULL */ { /* or end of linked list */ if((e = (struct entry *) calloc(1,sizeof(struct entry))) == NULL) fatal("Cannot allocate memory"); if((e->name = (char *) calloc(strlen(s)+1,sizeof(*s))) == NULL) fatal("Cannot allocate memory"); strcpy(e->name,s); e->next = NULL; if(!table[hashval]) table[hashval] = e; else laste->next = e; break; }#define equstr(a,b) ((a)[0] == (b)[0] ? strcmp((a),(b)) : 1) else if((i=equstr(e->name,s)) == 0) break; /* e points to entry */ else if(i>0) { /* create entry and link */ if((newe=(struct entry *) calloc(1, sizeof(struct entry))) == NULL) fatal("Cannot allocate memory"); if((newe->name=calloc(strlen(s)+1,sizeof(*s)))==NULL) fatal("Cannot allocate memory"); strcpy(newe->name,s); newe->next = e; if(laste == table[hashval]) table[hashval] = newe; else laste->next = newe; e = newe; /* set up e for return value */ break; } else { laste = e; e = e->next; } return(e->name);#else SYSV register char *t,*t0; if ( (t = t0 = calloc(strlen(s)+1,sizeof(char))) == NULL) fatal("out of memory"); while (*t++ = *s++); return(t0);#endif SYSV}CHARSTARconcat(a,b,c) /* c = concatenation of a and b */register CHARSTAR a, b;register CHARSTAR c;{ register CHARSTAR t; t = c; while(*t = *a++) t++; while(*t++ = *b++); return(c);}suffix(a,b,p) /* is b the suffix of a? if so, set p = prefix */register CHARSTAR a, b, p;{ register CHARSTAR a0, b0; a0 = a; b0 = b; if(!a || !b) return(0); while(*a++); while(*b++); if( (a-a0) < (b-b0) ) return(0); while(b>b0) if(*--a != *--b) return(0); while(a0<a) *p++ = *a0++; *p = CNULL; return(1);}/* this is now a macro calling private calloc -- rr int * intalloc(n)register int n;{ register INTSTAR p; if( p = (int *) calloc(1,n) ) return(p); fprintf(stderr,"out of memory"); fatal("out of memory");}*//* copy string a into b, substituting for arguments */extern NAMEBLOCK cur_name;CHARSTARsubst(a,b)register CHARSTAR a, b;{ register CHARSTAR s; static depth=0; char vname[100]; char closer; if(++depth > 100) fatal("infinitely recursive macro?"); if(a!=0) { while(*a) { if(*a != DOLLAR) *b++ = *a++; else if(*++a==CNULL || *a==DOLLAR) *b++ = *a++; else { s = vname; if( *a==LPAREN || *a==LCURLY ) { closer=(*a==LPAREN ? RPAREN : RCURLY); ++a; while(*a == BLANK) ++a; while( *a!=BLANK && *a!=closer && *a!=CNULL) *s++ = *a++; while(*a!=closer && *a!=CNULL) ++a; if(*a == closer) ++a; } else *s++ = *a++; *s = CNULL; if(amatch(&vname[0], "*:*=*")) b = colontrans(b, vname); else if(any("@*<%?", vname[0]) && vname[1]) b = dftrans(b, vname); else b = straightrans(b, vname); s++; } } } *b = CNULL; --depth; return(b);}/* * Translate the $(name:*=*) type things. */CHARSTARcolontrans(b, vname)register CHARSTAR b, vname;{ register CHARSTAR p; register CHARSTAR q = 0; char dftype = 0; register CHARSTAR pcolon; register VARBLOCK vbp; for(p = vname; *p && *p != KOLON; p++); pcolon = p; *pcolon = CNULL; if(any("@*<%?", vname[0])) { dftype = vname[1]; vname[1] = CNULL; } if((vbp = srchvar(vname)) == NULL) return(b); p = vbp->varval; if(dftype) { if((q = calloc(strlen(p)+2,1)) == NULL) fatal("Cannot alloc mem"); do_df(q, p, vname[1]); /* D/F trans gets smaller */ p = q; } if(p && *p) b = do_colon(b, p, pcolon+1); *pcolon = KOLON; if(dftype) vname[1] = dftype; if(q) cfree(q); return(b);}/* * Translate the $(name:*=*) type things. */CHARSTARdo_colon(to, from, trans)register CHARSTAR to, from, trans;{ register int i; register CHARSTAR p; register int leftlen; int len; char left[30], right[70]; char buf[128]; CHARSTAR pbuf; int lwig = 0; int rwig = 0; /* * Mark off the name (up to colon), the from expression (up to '='), * and the to expresion (up to CNULL). */ i = 0; while(*trans != EQUALS) left[i++] = *trans++; if(left[i-1] == WIGGLE) { lwig++; --i; } left[i] = CNULL; leftlen = i; i = 0; while(*++trans) right[i++] = *trans; if(right[i-1] == WIGGLE) { rwig++; --i; } right[i] = CNULL; /* * Now, tanslate. */ for(; len=getword(from,buf); from += len) { pbuf = buf; if((i = sindex(pbuf, left)) >= 0 && pbuf[i+leftlen] == CNULL && (lwig?((p=sdot(pbuf))!=(char *)0):1) ) { pbuf[i] = CNULL; if(!lwig && rwig) trysccs(pbuf); else if(lwig && !rwig) strshift(p, -2); catstr(to, pbuf); catstr(to, right); } else { catstr(to, pbuf); } } return(to);}getword(from, buf)register CHARSTAR from;register CHARSTAR buf;{ register int i = 0; if(*from == TAB || *from == BLANK) { while(*from == TAB || *from == BLANK) { *buf++ = *from++; ++i; } goto out; } while(*from && *from != TAB && *from != BLANK) { *buf++ = *from++; ++i; }out: *buf = CNULL; return(i);}/* * Do the $(@D) type translations. */CHARSTARdftrans(b, vname)register CHARSTAR b, vname;{ register char c1; register VARBLOCK vbp; c1 = vname[1]; vname[1] = CNULL; vbp = srchvar(vname); vname[1] = c1; if(vbp != 0 && *vbp->varval != 0) b = do_df(b, vbp->varval, c1); return(b);}#define lastslash(a) strrchr( (a) , SLASH )CHARSTARdo_df(b, str, type)register CHARSTAR b;register CHARSTAR str;char type;{ register CHARSTAR p; register int i; char buf[128]; *b = CNULL; for(; (i=getword(str, buf)); str += i) { if(buf[0] == BLANK || buf[0] == TAB) { catstr(b, buf); continue; } p = lastslash(buf); if(p) { *p = CNULL; catstr(b, type=='D'?(buf[0]==CNULL?"/":buf): p+1); *p = SLASH; } else catstr(b, type=='D'?".":buf); } return(b);}/* * Standard trnaslation, nothing fancy. */CHARSTARstraightrans(b, vname)register CHARSTAR b, vname;{ register VARBLOCK vbp; register CHAIN pchain; register NAMEBLOCK pn; vbp = srchvar(vname); if( vbp != 0) { if(vbp->v_aflg == YES && vbp->varval) { pchain = (CHAIN)vbp->varval; for(; pchain; pchain = pchain->nextchain) { pn = (NAMEBLOCK)pchain->datap; if(pn->alias) { catstr(b,pn->alias); } else { catstr(b,pn->namep); } *b++ = BLANK; } vbp->used = YES; } else if(*vbp->varval) { b = subst(vbp->varval, b); vbp->used = YES; } } return(b);}/* copy s into t, return the location of the next free character in s */CHARSTARcopstr(s, t)register CHARSTAR s, t;{ if(t == 0) return(s); while (*t) *s++ = *t++; *s = CNULL; return(s);}setvar(v,s)register CHARSTAR v, s;{ register VARBLOCK p; p = srchvar(v); if(p == 0) { p = varptr(v); } s = s?s:Nullstr; if (p->noreset == NO) { if(IS_ON(EXPORT)) p->envflg = YES; p->varval = s; if(IS_ON(INARGS) || IS_ON(ENVOVER)) p->noreset = YES; else p->noreset = NO; if(IS_ON(DBUG)) { printf( "setvar: %s = %s noreset = %d envflg = %d Mflags = 0%o\n", v, p->varval, p->noreset, p->envflg, Mflags); if(p->used && !amatch(v, "[@*<?!%]") ) fprintf(stderr, "Warning: %s changed after being used\n",v); } }}eqsign(a)register CHARSTAR a;{ register CHARSTAR p; for(p = ":;=$\n\t"; *p; p++) if(any(a, *p)) { callyacc(a); return(YES); } return(NO);}VARBLOCKvarptr(v)register CHARSTAR v;{ register VARBLOCK vp;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?