misc.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,261 行 · 第 1/2 页
C
1,261 行
if((vp = srchvar(v)) != 0) return(vp); vp = ALLOC(varblock); vp->nextvar = firstvar; firstvar = vp; vp->varname = copys(v); vp->varval = Nullstr; return(vp);}VARBLOCKsrchvar(vname)register CHARSTAR vname;{ register VARBLOCK vp; for(vp=firstvar; vp != 0 ; vp = vp->nextvar) if(equal(vname, vp->varname)) return(vp); return(NO);}/*VARARGS*/fatal1(s,t1,t2,t3)CHARSTAR s;{ char buf[100]; sprintf(buf, s, t1,t2,t3); fatal(buf);}fatal(s)CHARSTAR s;{ if(s) fprintf(stderr, "Make: %s. Stop.\n", s); else fprintf(stderr, "\nStop.\n");#ifdef unix mexit(1);#endif#ifdef gcos mexit(0);#endif}yyerror(s)CHARSTAR s;{ char buf[50]; extern int yylineno; sprintf(buf, "line %d: %s", yylineno, s); fatal(buf);}CHAINappendq(head,tail)register CHAIN head;register CHARSTAR tail;{ register CHAIN p; p = ALLOC(chain); p->datap = tail; while(head->nextchain) head = head->nextchain; head->nextchain = p;}CHARSTARmkqlist(p)register CHAIN p;{ register CHARSTAR qbufp, s; static char qbuf[OUTMAX]; qbufp = qbuf; for( ; p ; p = p->nextchain) { s = p->datap; if(qbufp != qbuf) *qbufp++ = BLANK; if(qbufp+strlen(s) > &qbuf[OUTMAX-3]) { fprintf(stderr, "$? list too long\n"); break; } while (*s) *qbufp++ = *s++; } *qbufp = CNULL; return(qbuf);}sindex(s1,s2)register CHARSTAR s1;register CHARSTAR s2;{ register CHARSTAR p1; register CHARSTAR p2; register int flag; register int ii; p1 = s1; p2 = s2; flag = -1; for(ii = 0; ; ii++) { while(*p1 == *p2) { if(flag < 0) flag = ii; if(*p1++ == CNULL) return(flag); p2++; } if(*p2 == CNULL) return(flag); if(flag >= 0) { flag = -1; p2 = s2; } if(*s1++ == CNULL) return(flag); p1 = s1; }}#include "sys/types.h"#include "sys/stat.h"/* * findfl(name) (like execvp, but does path search and finds files) */static char fname[128];CHARSTAR execat();CHARSTARfindfl(name)register CHARSTAR name;{ register CHARSTAR p; register VARBLOCK cp; if(name[0] == SLASH) return(name); cp = varptr("VPATH"); if(*cp->varval == 0) p = ":"; else p = cp->varval; do { p = execat(p, name, fname); if(access(fname, 4) == 0) return(fname); } while (p); return((CHARSTAR )-1);}CHARSTARexecat(s1, s2, si)register CHARSTAR s1, s2;register CHARSTAR si;{ register CHARSTAR s; s = si; while (*s1 && *s1 != KOLON && *s1 != MINUS) *s++ = *s1++; if (si != s) *s++ = SLASH; while (*s2) *s++ = *s2++; *s = CNULL; return(*s1? ++s1: 0);}/* * change xx to s.xx or /x/y/z to /x/y/s.z */CHARSTARtrysccs(str)register CHARSTAR str;{ register CHARSTAR sstr; register int i = 2; sstr = str; for(; *str; str++); str[2] = CNULL; str--; for(;str >= sstr; str--) { if(*str == SLASH) if(i == 2) { i = 0; *(str+2) = DOT; *(str+1) = 's'; } *(str+i) = *str; } if(i == 2) { *(str+2) = DOT; *(str+1) = 's'; } return(sstr);}is_sccs(p)register CHARSTAR p;{#define ESS 's' if (*p == ESS && *(p+1) == DOT) return(YES); for(p++;*p;p++) if(*p == SLASH && *(p+1) == ESS && *(p+2) == DOT) return(YES); return(NO);}CHARSTARsdot(p)register char *p;{ if (*p == ESS && *(p+1) == DOT) return(p); for(p++;*p;p++) if(*p == SLASH && *(p+1) == ESS && *(p+2) == DOT) return(p); return(NULL);}/* * change pfx to /xxx/yy/*zz.* or *zz.* */CHARSTARaddstars(pfx)register CHARSTAR pfx;{ register CHARSTAR p1, p2; for(p1 = pfx; *p1; p1++); p2 = p1 + 3; /* 3 characters, '*', '.', and '*'. */ p1--; *p2-- = CNULL; *p2-- = STAR; *p2-- = DOT; while(p1 >= pfx) { if(*p1 == SLASH) { *p2 = STAR; return(pfx); } *p2-- = *p1--; } *p2 = STAR; return(p2);}#define NENV 300extern CHARSTAR *environ;/* * This routine is called just before an exec. */setenv(){ register CHARSTAR *ea; register int nenv = 0; register CHARSTAR p; register CHARSTAR *es; register VARBLOCK vp; register int length; if(firstvar == 0) return; es=ea=(CHARSTAR *)calloc(NENV, sizeof *ea); if(es == NULL) fatal("Cannot alloc mem for envp."); for(vp=firstvar; vp != 0; vp=vp->nextvar) if(vp->envflg) { if(++nenv >= NENV) fatal("Too many env parameters."); length = strlen(vp->varname) + strlen(vp->varval) + 2; if((*ea = calloc(length, sizeof **ea)) == NULL) fatal("Cannot alloc mem for env."); p = *ea++; catstr(p,vp->varname); *p++ = '='; catstr(p,vp->varval); } *ea = 0; if(nenv > 0) environ=es; if(IS_ON(DBUG)) printf("nenv = %d\n", nenv);}/* * Called in main * If a string like "CC=" occurs then CC is not put in environment. * This is because there is no good way to remove a variable * from the environment within the shell. * When in posix mode always ignore value of SHELL envir var. */readenv(){ register CHARSTAR *ea; register CHARSTAR p; ea=environ; for(;*ea; ea++) { for(p = *ea; *p && *p != EQUALS; p++); if(*p == EQUALS) if(*(p+1)) { if(sysvmode == POSIX_ON){ if(strncmp(*ea,"SHELL=",6)) eqsign(*ea); } else eqsign(*ea); } }}sccstrip(pstr)register CHARSTAR pstr;{ register CHARSTAR p2; register CHARSTAR sstr; sstr = pstr; for(; *pstr ; pstr++) if(*pstr == RCURLY) { if(isdigit(pstr[1]) && pstr!=sstr && pstr[-1] != DOLLAR) { for(p2 = pstr; *p2 && (*p2 != LCURLY); p2++); if(*p2 == CNULL) break; strshift(pstr, -(int)(p2-pstr+1) ); } }}/* * Shift a string `pstr' count places. negative is left, pos is right * Negative shifts cause char's at front to be lost. * Positive shifts assume enough space! */CHARSTARstrshift(pstr, count)register CHARSTAR pstr;register int count;{ register CHARSTAR sstr; sstr = pstr; if(count < 0) { for(count = -count; *pstr=pstr[count]; pstr++); *pstr = 0; return(sstr); } for(; *pstr; pstr++); do { pstr[count] = *pstr; } while (pstr--, count--); return(sstr);}/* * execlp(name, arg,...,0) (like execl, but does path search) * execvp(name, argv) (like execv, but does path search) */#include <errno.h>#define NULL 0CHARSTAR execat();extern errno;execlp(name, argv)CHARSTAR name, argv;{ return(execvp(name, &argv));}execvp(name, argv)CHARSTAR name, *argv;{ register etxtbsy = 1; register eacces = 0; register CHARSTAR cp; register CHARSTAR pathstr; register CHARSTAR shell;#if 0 char fname[128];#endif 0 pathstr = varptr("PATH")->varval; if(pathstr == 0 || *pathstr == CNULL) pathstr = ":/bin:/usr/bin"; shell = varptr("SHELL")->varval; if(shell == 0 || *shell == CNULL || sysvmode==0) shell = SHELLCOM; cp = any(name, SLASH)? "": pathstr; do { cp = execat(cp, name, fname);retry: execv(fname, argv); switch(errno) { case ENOEXEC: *argv = fname; *--argv = "sh"; execv(shell, argv); return(-1); case ETXTBSY: if (++etxtbsy > 5) return(-1); sleep(etxtbsy); goto retry; case EACCES: eacces++; break; case ENOMEM: case E2BIG: return(-1); } } while (cp); if (eacces) errno = EACCES; return(-1);}/* * get() does an SCCS get on the file ssfile. * For the get command, get() uses the value of the variable "GET". * If ssfile has a slash in it, get() does a "chdir" to the appropriate * directory if the cdflag is set to CD. This assures * the program finds the ssfile where it belongs when necessary. * If the rlse string variable is set, get() uses it in the * get command sequence. * Thus a possible sequence is: * set -x; * cd ../sys/head; * get -r2.3.4.5 s.stdio.h * *//* * The gothead and gotf structures are used to remember * the names of the files `make' automatically gets so * `make' can remove them upon exit. */GOTHEAD gotfiles;get(ssfile, cdflag, rlse)register CHARSTAR ssfile;register int cdflag;register CHARSTAR rlse;{ register CHARSTAR pr; register CHARSTAR pr1; char gbuf[128]; char sfile[128]; register int retval; GOTF gf; pr = sfile; strcpy(pr, ssfile); if(!sdot(sfile)) trysccs(sfile); if(access(sfile, 4) != 0 && IS_OFF(GET)) return(NO); pr = gbuf; if(IS_OFF(SIL)) catstr(pr, "set -x;\n"); if(cdflag == CD) if(any(sfile, SLASH)) { catstr(pr, "cd "); for(pr1 = sfile; *pr1; pr1++); while(*pr1 != SLASH) pr1--; *pr1 = CNULL; catstr(pr, sfile); catstr(pr, ";\n"); *pr1 = SLASH; } catstr(pr, varptr("GET")->varval); *pr++ = ' '; catstr(pr, varptr("GFLAGS")->varval); *pr++ = ' '; pr1 = rlse; if(pr1 != NULL && pr1[0] != CNULL) { if(pr1[0] != MINUS) /* RELEASE doesn't have '-r' */ catstr(pr, "-r"); catstr(pr, pr1); *pr++ = ' '; } strcpy(pr, sfile); /* * exit codes are opposite of error codes so do the following: */ retval = (system(gbuf) == 0) ? YES : NO ; if(retval == YES) { if(gotfiles == 0) { gotfiles = ALLOC(gothead); gf = (GOTF)gotfiles; gotfiles->gnextp = 0; gotfiles->endp = (GOTF)gotfiles; } else { gf = gotfiles->endp; gf->gnextp = ALLOC(gotf); gf = gf->gnextp; gf->gnextp = 0; } gf->gnamep = copys(sfile+2); /* `+2' skips `s.' */ gotfiles->endp = gf; } return(retval);}/* * subroutine to actually remove to gotten files. */rm_gots(){ register GOTF gf; if(IS_ON(GF_KEEP)) return; for(gf = (GOTF)gotfiles; gf ; gf=gf->gnextp) if(gf->gnamep) { if(IS_ON(DBUG))printf("rm_got: %s\n", gf->gnamep); unlink(gf->gnamep); }}callyacc(str)register CHARSTAR str;{ CHARSTAR lines[2]; FILE *finsave; CHARSTAR *lpsave; finsave = fin; lpsave = linesptr; fin = 0; lines[0] = str; lines[1] = 0; linesptr = lines; yyparse(); fin = finsave; linesptr = lpsave;}/* * exit routine for removing the files `make' automatically * got. */mexit(arg){ rm_gots(); if(IS_ON(MEMMAP)) { prtmem(); } if(IS_ON(DBUG)) { char pathname[MAXPATHLEN]; if(getwd(pathname) == 0) { fprintf(stderr, "error trying to get current working directory, %s\n", pathname); } else { printf("Current working directory on exit from make is %s\n", pathname); } } exit(arg);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?