1*30490Slepreau static char Sccsid[] "@(#)bal	2.1";
2*30490Slepreau #
3*30490Slepreau /*
4*30490Slepreau 	Function to find the position, in str, of the first of the char-
5*30490Slepreau 	acters in end occurring outside a balanced string.  A balanced string
6*30490Slepreau 	contains matched occurrences of any character in open and the corres-
7*30490Slepreau 	ponding character in clos.  Balanced strings may be nested.  The null
8*30490Slepreau 	at the end of str is considered to belong to end.  Unmatched members
9*30490Slepreau 	of open or clos result in an error return.
10*30490Slepreau */
11*30490Slepreau 
12*30490Slepreau #define ifany(x) for (p=x; *p; p++) if (c == *p)
13*30490Slepreau #define matching_clos clos[p-open]
14*30490Slepreau #define error -1
15*30490Slepreau #define position s-str-1
16*30490Slepreau 
17*30490Slepreau balbrk(str,open,clos,end)
18*30490Slepreau char *str,*open,*clos,*end;
19*30490Slepreau {
20*30490Slepreau 	register char *p, *s, c;
21*30490Slepreau 	char opp[2];
22*30490Slepreau 	opp[1] = '\0';
23*30490Slepreau 	for (s = str; c = *s++;  ) {
24*30490Slepreau 		ifany(end) return position;
25*30490Slepreau 		ifany(clos) return error;
26*30490Slepreau 		ifany(open) {
27*30490Slepreau 			opp[0] = matching_clos;
28*30490Slepreau 			s =+ balbrk(s,open,clos,opp);
29*30490Slepreau 			if (*s++ != matching_clos) return error;
30*30490Slepreau 			break;
31*30490Slepreau 		}
32*30490Slepreau 	}
33*30490Slepreau 	return position;
34*30490Slepreau }
35