1*30493Slepreau static char Sccsid[] = "@(#)bal.c	1.2	02/15/87";
2*30493Slepreau 
330490Slepreau /*
430490Slepreau 	Function to find the position, in str, of the first of the char-
530490Slepreau 	acters in end occurring outside a balanced string.  A balanced string
630490Slepreau 	contains matched occurrences of any character in open and the corres-
730490Slepreau 	ponding character in clos.  Balanced strings may be nested.  The null
830490Slepreau 	at the end of str is considered to belong to end.  Unmatched members
930490Slepreau 	of open or clos result in an error return.
1030490Slepreau */
1130490Slepreau 
1230490Slepreau #define ifany(x) for (p=x; *p; p++) if (c == *p)
1330490Slepreau #define matching_clos clos[p-open]
1430490Slepreau #define error -1
1530490Slepreau #define position s-str-1
1630490Slepreau 
balbrk(str,open,clos,end)1730490Slepreau balbrk(str,open,clos,end)
1830490Slepreau char *str,*open,*clos,*end;
1930490Slepreau {
2030490Slepreau 	register char *p, *s, c;
2130490Slepreau 	char opp[2];
2230490Slepreau 	opp[1] = '\0';
2330490Slepreau 	for (s = str; c = *s++;  ) {
2430490Slepreau 		ifany(end) return position;
2530490Slepreau 		ifany(clos) return error;
2630490Slepreau 		ifany(open) {
2730490Slepreau 			opp[0] = matching_clos;
28*30493Slepreau 			s += balbrk(s,open,clos,opp);
2930490Slepreau 			if (*s++ != matching_clos) return error;
3030490Slepreau 			break;
3130490Slepreau 		}
3230490Slepreau 	}
3330490Slepreau 	return position;
3430490Slepreau }
35