1 /* args.c 4.1 82/05/07 */ 2 3 # 4 /* 5 * UNIX shell 6 * 7 * S. R. Bourne 8 * Bell Telephone Laboratories 9 * 10 */ 11 12 #include "defs.h" 13 14 PROC STRING *copyargs(); 15 LOCAL DOLPTR dolh; 16 17 CHAR flagadr[10]; 18 19 CHAR flagchar[] = { 20 'x', 'n', 'v', 't', 's', 'i', 'e', 'r', 'k', 'u', 0 21 }; 22 INT flagval[] = { 23 execpr, noexec, readpr, oneflg, stdflg, intflg, errflg, rshflg, keyflg, setflg, 0 24 }; 25 26 /* ======== option handling ======== */ 27 28 29 INT options(argc,argv) 30 STRING *argv; 31 INT argc; 32 { 33 REG STRING cp; 34 REG STRING *argp=argv; 35 REG STRING flagc; 36 STRING flagp; 37 38 IF argc>1 ANDF *argp[1]=='-' 39 THEN cp=argp[1]; 40 flags &= ~(execpr|readpr); 41 WHILE *++cp 42 DO flagc=flagchar; 43 44 WHILE *flagc ANDF *flagc != *cp DO flagc++ OD 45 IF *cp == *flagc 46 THEN flags |= flagval[flagc-flagchar]; 47 ELIF *cp=='c' ANDF argc>2 ANDF comdiv==0 48 THEN comdiv=argp[2]; 49 argp[1]=argp[0]; argp++; argc--; 50 ELSE failed(argv[1],badopt); 51 FI 52 OD 53 argp[1]=argp[0]; argc--; 54 FI 55 56 /* set up $- */ 57 flagc=flagchar; 58 flagp=flagadr; 59 WHILE *flagc 60 DO IF flags&flagval[flagc-flagchar] 61 THEN *flagp++ = *flagc; 62 FI 63 flagc++; 64 OD 65 *flagp++=0; 66 67 return(argc); 68 } 69 70 VOID setargs(argi) 71 STRING argi[]; 72 { 73 /* count args */ 74 REG STRING *argp=argi; 75 REG INT argn=0; 76 77 WHILE Rcheat(*argp++)!=ENDARGS DO argn++ OD 78 79 /* free old ones unless on for loop chain */ 80 freeargs(dolh); 81 dolh=copyargs(argi,argn); /* sets dolv */ 82 assnum(&dolladr,dolc=argn-1); 83 } 84 85 freeargs(blk) 86 DOLPTR blk; 87 { 88 REG STRING *argp; 89 REG DOLPTR argr=0; 90 REG DOLPTR argblk; 91 92 IF argblk=blk 93 THEN argr = argblk->dolnxt; 94 IF (--argblk->doluse)==0 95 THEN FOR argp=argblk->dolarg; Rcheat(*argp)!=ENDARGS; argp++ 96 DO free(*argp) OD 97 free(argblk); 98 FI 99 FI 100 return(argr); 101 } 102 103 LOCAL STRING * copyargs(from, n) 104 STRING from[]; 105 { 106 REG STRING * np=alloc(sizeof(STRING*)*n+3*BYTESPERWORD); 107 REG STRING * fp=from; 108 REG STRING * pp=np; 109 110 np->doluse=1; /* use count */ 111 np=np->dolarg; 112 dolv=np; 113 114 WHILE n-- 115 DO *np++ = make(*fp++) OD 116 *np++ = ENDARGS; 117 return(pp); 118 } 119 120 clearup() 121 { 122 /* force `for' $* lists to go away */ 123 WHILE argfor=freeargs(argfor) DONE 124 125 /* clean up io files */ 126 WHILE pop() DONE 127 } 128 129 DOLPTR useargs() 130 { 131 IF dolh 132 THEN dolh->doluse++; 133 dolh->dolnxt=argfor; 134 return(argfor=dolh); 135 ELSE return(0); 136 FI 137 } 138