|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 2994 (0xbb2) Types: TextFile Notes: UNIX file Names: »equiv.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─⟦this⟧ »cmd/egrep/equiv.c«
/* * equivalence classes */ #include <ctype.h> #include "egrep.h" #include "newt.h" #include "eclass.h" char etab[NCHARS]; /* map ASCII to eclass # */ struct eclass *eclasses; /* head of eclass list */ bool intersect( ); struct eclass *neweclass( ); /* * check equivalence * A set of eclasses must exist such that their union equals the * chars in `np'. If not, the equivalence relation must be "refined". */ equiv( np) register struct newt *np; { register struct eclass *ep, *p; struct eclass e; if (eclasses == NULL) { eclasses = neweclass( ); eclasses->e_c = 0; eclasses->e_b = newbits( TRUE); eclasses->e_next = NULL; eclasses->e_class = n_ec++; } for (ep=eclasses; ep; ep=ep->e_next) { if (not intersect( np, ep, &e)) continue; p = neweclass( ); *p = e; p->e_class = n_ec++; p->e_next = eclasses; eclasses = p; } } /* * is there a transition? * Return TRUE if there is a transition from `np' on the chars given * by `ep'. */ bool eqtrans( ep, np) register struct eclass *ep; register struct newt *np; { register i; if (ep->e_b) { if (np->n_b) { for (i=0; i<NCHARS/NBCHAR; ++i) if (ep->e_b[i] & np->n_b[i]) return (TRUE); } else return (bittst( np->n_c, ep->e_b)); } else { if (np->n_b) return (bittst( ep->e_c, np->n_b)); else return (ep->e_c == np->n_c); } return (FALSE); } /* * intersect char sets * If the intersection of `np' and `ep0' is a proper subset of `ep0', * then store the intersection in `ep1', store the difference of * `ep0' - `ep1' in `ep0' and return TRUE. */ static bool intersect( np, ep0, ep1) register struct newt *np; register struct eclass *ep0; struct eclass *ep1; { register i; bool classcheck( ); if (ep0->e_b == NULL) return (FALSE); if (np->n_b == NULL) { i = np->n_c; if (not bittst( i, ep0->e_b)) return (FALSE); bitclr( i, ep0->e_b); ep1->e_c = i; etab[i] = n_ec; ep1->e_b = NULL; } else { if (not classcheck( np->n_b, ep0->e_b)) return (FALSE); ep1->e_b = newbits( FALSE); for (i=0; i<NCHARS/NBCHAR; ++i) { ep1->e_b[i] = ep0->e_b[i] & np->n_b[i]; ep0->e_b[i] &= ~np->n_b[i]; } for (i=0; i<NCHARS; ++i) if (bittst( i, ep1->e_b)) etab[i] = n_ec; ep1->e_c = 0; } return (TRUE); } /* * check intersection * Specific check for char sets represented as bitmaps. If the * intersection of `p' and `q' is a proper subset of `q' return TRUE. * Non-modifying nature of this routine is optimized for the "-y" option, * where intersections of [Aa] and [Bb] are commonplace. */ static bool classcheck( p, q) register char *p, *q; { register i; bool k1, k2; k1 = FALSE; k2 = FALSE; i = NCHARS / NBCHAR; do { if (*q & *p) k1 = TRUE; if (*q++ & ~*p++) k2 = TRUE; } while (--i); return (k1 && k2); } /* * allocate new eclass */ static struct eclass * neweclass( ) { register struct eclass *ep; ep = malloc( sizeof *ep); if (ep == NULL) nomem( ); return (ep); }