4.3BSD/usr/contrib/icon/functions/bal.c

Compare this file to the similar file:
Show the results in this format:

#include "../h/rt.h"

/*
 * bal(c1,c2,c3,s,i,j) - find end of a balanced substring of s[i:j].
 *  Generates successive positions.
 */

Xbal(nargs, arg6, arg5, arg4, arg3, arg2, arg1, arg0)
int nargs;
struct descrip arg6, arg5, arg4, arg3, arg2, arg1, arg0;
   {
   register int i, j, cnt;
   register c;
   int t;
   long l1, l2;
   int *cs1, *cs2, *cs3;
   int csbuf1[CSETSIZE], csbuf2[CSETSIZE], csbuf3[CSETSIZE];
   char sbuf[MAXSTRING];
   static int lpar[CSETSIZE] =	/* '(' */
      cset_display(0, 0, 0400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
   static int rpar[CSETSIZE] =	/* ')' */
      cset_display(0, 0, 01000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

   /*
    *  c1 defaults to &cset; c2 defaults to '(' (lpar); c3 defaults to
    *   ')' (rpar); s to &subject; i to &pos if s defaulted, 1 otherwise;
    *   j defaults to 0.
    */
   defcset(&arg1, &cs1, csbuf1, k_cset.bits);
   defcset(&arg2, &cs2, csbuf2, lpar);
   defcset(&arg3, &cs3, csbuf3, rpar);
   if (defstr(&arg4, sbuf, &k_subject))
      defint(&arg5, &l1, k_pos);
   else
      defint(&arg5, &l1, 1);
   defint(&arg6, &l2, 0);

   /*
    * Convert i and j to positions in s and order them.
    */
   i = cvpos(l1, STRLEN(arg4));
   j = cvpos(l2, STRLEN(arg4));
   if (i > j) {
      t = i;
      i = j;
      j = t;
      }

   /*
    * Loop through characters in s[i:j].  When a character in cs2 is
    *  found, increment cnt; when a chracter in cs3 is found, decrement
    *  cnt.  When cnt is 0 there have been an equal number of occurrences
    *  of characters in cs2 and cs3, i.e., the string to the left of
    *  i is balanced.  If the string is balanced and the current character
    *  (s[i]) is in c1, suspend i.  Note that if cnt drops below zero,
    *  bal fails.
    */
   cnt = 0;
   while (i < j) {
      c = STRLOC(arg4)[i-1];
      if (cnt == 0 && tstb(c, cs1)) {
         arg0.type = D_INTEGER;
         INTVAL(arg0) = i;
         suspend();
         }
      if (tstb(c, cs2))
         cnt++;
      else if (tstb(c, cs3))
         cnt--;
      if (cnt < 0)
         fail();
      i++;
      }
   /*
    * Eventually fail.
    */
   fail();
   }

Procblock(bal,6)