|
|
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.