|
|
1.1 root 1: /*
2: * File: lscan.c
3: * Contents: bscan, escan
4: */
5:
6: #include "../h/rt.h"
7:
8: /*
9: * bscan - set &subject and &pos upon entry to a scanning expression.
10: *
11: * Arguments are:
12: * cargp[-2] - new value for &subject
13: * cargp[-1] - saved value of &subject
14: * cargp[0] - saved value of &pos
15: */
16:
17: #define newsubj (cargp[-2])
18: #define savsubj (cargp[-1])
19: #define savpos (cargp[0])
20:
21: LibDcl(bscan,2,"?")
22: {
23: char sbuf[MaxCvtLen];
24: extern char *alcstr();
25: struct descrip tsubject;
26:
27: /*
28: * Make a copy of the value for &subject and convert it to a string.
29: */
30: tsubject = newsubj;
31: DeRef(tsubject);
32: switch (cvstr(&tsubject, sbuf)) {
33: case NULL:
34: runerr(103, &tsubject);
35:
36: case Cvt:
37: /*
38: * The new value for &subject wasn't a string. Allocate the
39: * new value and fall through.
40: */
41: strreq(StrLen(tsubject));
42: StrLoc(tsubject) = alcstr(StrLoc(tsubject), StrLen(tsubject));
43:
44: case NoCvt:
45: /*
46: * Establish a new &subject value and set &pos to 1.
47: */
48: k_subject = tsubject;
49: k_pos = 1;
50: }
51: Suspend;
52:
53: /*
54: * bscan has been resumed. Restore the old &subject and &pos values
55: * and fail.
56: */
57: k_subject = savsubj;
58: k_pos = IntVal(savpos);
59: Fail;
60: }
61:
62:
63: /*
64: * escan - restore &subject and &pos at the end of a scanning expression.
65: *
66: * Arguments:
67: * Arg0 - value being scanned
68: * Arg1 - old value of &subject
69: * Arg2 - old value of &pos
70: * Arg3 - result of the scanning expression
71: *
72: * The result of the scanning expression is dereferenced if it refers to &subject
73: * or &pos, then copied to the first argument (the last three will
74: * be popped when escan returns). Then the previous values of &subject
75: * and &pos are restored.
76: *
77: * Escan suspends once it has restored the old &subject; on failure
78: * the new &subject and &pos are "unrestored", and the failure is
79: * propagated into the using clause.
80: */
81:
82: LibDcl(escan,3,"escan")
83: {
84: struct descrip tmp;
85:
86: /*
87: * If the result of the scanning expression is &subject or &pos,
88: * it is dereferenced.
89: */
90: if (((word)BlkLoc(Arg3) == (word)&tvky_sub) || ((word)BlkLoc(Arg3) == (word)&tvky_pos))
91: DeRef(Arg3);
92:
93: /*
94: * Copy the result of the scanning expression into Arg0, which will
95: * be the result of the scan.
96: */
97: Arg0 = Arg3;
98:
99: /*
100: * Swap new and old values of &subject, leaving the new value in Arg1.
101: */
102: tmp = k_subject;
103: k_subject = Arg1;
104: Arg1 = tmp;
105:
106: /*
107: * Swap new and old values of &pos, leaving the new value in Arg2.
108: */
109: tmp = Arg2;
110: IntVal(Arg2) = k_pos;
111: k_pos = IntVal(tmp);
112:
113: /*
114: * Suspend the value of the scanning expression.
115: */
116: Suspend;
117:
118: /*
119: * Upon resumption, restore the new values for &subject and &pos
120: * and fail.
121: */
122: k_subject = Arg1;
123: k_pos = IntVal(Arg2);
124:
125: Fail;
126: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.