1: #ifndef lint
2: static char sccsid[] = "@(#)macro.c 4.3 8/11/83";
3: #endif
4:
5: #
6: /*
7: * UNIX shell
8: *
9: * S. R. Bourne
10: * Bell Telephone Laboratories
11: *
12: */
13:
14: #include "defs.h"
15: #include "sym.h"
16:
17: LOCAL CHAR quote; /* used locally */
18: LOCAL CHAR quoted; /* used locally */
19:
20:
21:
22: LOCAL STRING copyto(endch)
23: REG CHAR endch;
24: {
25: REG CHAR c;
26:
27: WHILE (c=getch(endch))!=endch ANDF c
28: DO pushstak(c|quote) OD
29: zerostak();
30: IF c!=endch THEN error(badsub) FI
31: }
32:
33: LOCAL skipto(endch)
34: REG CHAR endch;
35: {
36: /* skip chars up to } */
37: REG CHAR c;
38: WHILE (c=readc()) ANDF c!=endch
39: DO SWITCH c IN
40:
41: case SQUOTE: skipto(SQUOTE); break;
42:
43: case DQUOTE: skipto(DQUOTE); break;
44:
45: case DOLLAR: IF readc()==BRACE
46: THEN skipto('}');
47: FI
48: ENDSW
49: OD
50: IF c!=endch THEN error(badsub) FI
51: }
52:
53: LOCAL getch(endch)
54: CHAR endch;
55: {
56: REG CHAR d;
57:
58: retry:
59: d=readc();
60: IF !subchar(d)
61: THEN return(d);
62: FI
63: IF d==DOLLAR
64: THEN REG INT c;
65: IF (c=readc(), dolchar(c))
66: THEN NAMPTR n=NIL;
67: INT dolg=0;
68: BOOL bra;
69: REG STRING argp, v;
70: CHAR idb[2];
71: STRING id=idb;
72:
73: IF bra=(c==BRACE) THEN c=readc() FI
74: IF letter(c)
75: THEN argp=relstak();
76: WHILE alphanum(c) DO pushstak(c); c=readc() OD
77: zerostak();
78: n=lookup(absstak(argp)); setstak(argp);
79: v = n->namval; id = n->namid;
80: peekc = c|MARK;;
81: ELIF digchar(c)
82: THEN *id=c; idb[1]=0;
83: IF astchar(c)
84: THEN dolg=1; c='1';
85: FI
86: c -= '0';
87: v=((c==0) ? cmdadr : (c<=dolc) ? dolv[c] : (dolg=0));
88: ELIF c=='$'
89: THEN v=pidadr;
90: ELIF c=='!'
91: THEN v=pcsadr;
92: ELIF c=='#'
93: THEN v=dolladr;
94: ELIF c=='?'
95: THEN v=exitadr;
96: ELIF c=='-'
97: THEN v=flagadr;
98: ELIF bra THEN error(badsub);
99: ELSE goto retry;
100: FI
101: c = readc();
102: IF !defchar(c) ANDF bra
103: THEN error(badsub);
104: FI
105: argp=0;
106: IF bra
107: THEN IF c!='}'
108: THEN argp=relstak();
109: IF (v==0)NEQ(setchar(c))
110: THEN copyto('}');
111: ELSE skipto('}');
112: FI
113: argp=absstak(argp);
114: FI
115: ELSE peekc = c|MARK; c = 0;
116: FI
117: IF v
118: THEN IF c!='+'
119: THEN LOOP WHILE c = *v++
120: DO pushstak(c|quote); OD
121: IF dolg==0 ORF (++dolg>dolc)
122: THEN break;
123: ELSE v=dolv[dolg]; pushstak(SP|(*id=='*' ? quote : 0));
124: FI
125: POOL
126: FI
127: ELIF argp
128: THEN IF c=='?'
129: THEN failed(id,*argp?argp:badparam);
130: ELIF c=='='
131: THEN IF n
132: THEN assign(n,argp);
133: ELSE error(badsub);
134: FI
135: FI
136: ELIF flags&setflg
137: THEN failed(id,badparam);
138: FI
139: goto retry;
140: ELSE peekc=c|MARK;
141: FI
142: ELIF d==endch
143: THEN return(d);
144: ELIF d==SQUOTE
145: THEN comsubst(); goto retry;
146: ELIF d==DQUOTE
147: THEN quoted++; quote^=QUOTE; goto retry;
148: FI
149: return(d);
150: }
151:
152: STRING macro(as)
153: STRING as;
154: {
155: /* Strip "" and do $ substitution
156: * Leaves result on top of stack
157: */
158: REG BOOL savqu =quoted;
159: REG CHAR savq = quote;
160: FILEHDR fb;
161:
162: push(&fb); estabf(as);
163: usestak();
164: quote=0; quoted=0;
165: copyto(0);
166: pop();
167: IF quoted ANDF (stakbot==staktop) THEN pushstak(QUOTE) FI
168: quote=savq; quoted=savqu;
169: return(fixstak());
170: }
171:
172: LOCAL comsubst()
173: {
174: /* command substn */
175: FILEBLK cb;
176: REG CHAR d;
177: REG STKPTR savptr = fixstak();
178:
179: usestak();
180: WHILE (d=readc())!=SQUOTE ANDF d
181: DO pushstak(d) OD
182:
183: BEGIN
184: REG STRING argc;
185: trim(argc=fixstak());
186: push(&cb); estabf(argc);
187: END
188: BEGIN
189: REG TREPTR t = makefork(FPOU,cmd(EOFSYM,MTFLG|NLFLG));
190: INT pv[2];
191:
192: /* this is done like this so that the pipe
193: * is open only when needed
194: */
195: chkpipe(pv);
196: initf(pv[INPIPE]);
197: execute(t, 0, 0, pv);
198: close(pv[OTPIPE]);
199: END
200: tdystak(savptr); staktop=movstr(savptr,stakbot);
201: WHILE d=readc() DO locstak(); pushstak(d|quote) OD
202: await(0);
203: WHILE stakbot!=staktop
204: DO IF (*--staktop&STRIP)!=NL
205: THEN ++staktop; break;
206: FI
207: OD
208: pop();
209: }
210:
211: #define CPYSIZ 512
212:
213: subst(in,ot)
214: INT in, ot;
215: {
216: REG CHAR c;
217: FILEBLK fb;
218: REG INT count=CPYSIZ;
219:
220: push(&fb); initf(in);
221: /* DQUOTE used to stop it from quoting */
222: WHILE c=(getch(DQUOTE)&STRIP)
223: DO pushstak(c);
224: IF --count == 0
225: THEN flush(ot); count=CPYSIZ;
226: FI
227: OD
228: flush(ot);
229: pop();
230: }
231:
232: LOCAL flush(ot)
233: {
234: write(ot,stakbot,staktop-stakbot);
235: IF flags&execpr THEN write(output,stakbot,staktop-stakbot) FI
236: staktop=stakbot;
237: }
Defined functions
getch
defined in line
53; used 2 times
Defined variables
sccsid
defined in line
2;
never used
Defined macros