1: #include "../h/rt.h" 2: 3: /* 4: * bal(c1,c2,c3,s,i,j) - find end of a balanced substring of s[i:j]. 5: * Generates successive positions. 6: */ 7: 8: Xbal(nargs, arg6, arg5, arg4, arg3, arg2, arg1, arg0) 9: int nargs; 10: struct descrip arg6, arg5, arg4, arg3, arg2, arg1, arg0; 11: { 12: register int i, j, cnt; 13: register c; 14: int t; 15: long l1, l2; 16: int *cs1, *cs2, *cs3; 17: int csbuf1[CSETSIZE], csbuf2[CSETSIZE], csbuf3[CSETSIZE]; 18: char sbuf[MAXSTRING]; 19: static int lpar[CSETSIZE] = /* '(' */ 20: cset_display(0, 0, 0400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 21: static int rpar[CSETSIZE] = /* ')' */ 22: cset_display(0, 0, 01000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 23: 24: /* 25: * c1 defaults to &cset; c2 defaults to '(' (lpar); c3 defaults to 26: * ')' (rpar); s to &subject; i to &pos if s defaulted, 1 otherwise; 27: * j defaults to 0. 28: */ 29: defcset(&arg1, &cs1, csbuf1, k_cset.bits); 30: defcset(&arg2, &cs2, csbuf2, lpar); 31: defcset(&arg3, &cs3, csbuf3, rpar); 32: if (defstr(&arg4, sbuf, &k_subject)) 33: defint(&arg5, &l1, k_pos); 34: else 35: defint(&arg5, &l1, 1); 36: defint(&arg6, &l2, 0); 37: 38: /* 39: * Convert i and j to positions in s and order them. 40: */ 41: i = cvpos(l1, STRLEN(arg4)); 42: j = cvpos(l2, STRLEN(arg4)); 43: if (i > j) { 44: t = i; 45: i = j; 46: j = t; 47: } 48: 49: /* 50: * Loop through characters in s[i:j]. When a character in cs2 is 51: * found, increment cnt; when a chracter in cs3 is found, decrement 52: * cnt. When cnt is 0 there have been an equal number of occurrences 53: * of characters in cs2 and cs3, i.e., the string to the left of 54: * i is balanced. If the string is balanced and the current character 55: * (s[i]) is in c1, suspend i. Note that if cnt drops below zero, 56: * bal fails. 57: */ 58: cnt = 0; 59: while (i < j) { 60: c = STRLOC(arg4)[i-1]; 61: if (cnt == 0 && tstb(c, cs1)) { 62: arg0.type = D_INTEGER; 63: INTVAL(arg0) = i; 64: suspend(); 65: } 66: if (tstb(c, cs2)) 67: cnt++; 68: else if (tstb(c, cs3)) 69: cnt--; 70: if (cnt < 0) 71: fail(); 72: i++; 73: } 74: /* 75: * Eventually fail. 76: */ 77: fail(); 78: } 79: 80: Procblock(bal,6)