/* ecs - equivalence class routines */

/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Vern Paxson.
 * 
 * The United States Government has rights in this work pursuant
 * to contract no. DE-AC03-76SF00098 between the United States
 * Department of Energy and the University of California.
 *
 * Redistribution and use in source and binary forms with or without
 * modification are permitted provided that: (1) source distributions retain
 * this entire copyright notice and comment, and (2) distributions including
 * binaries display the following acknowledgement:  ``This product includes
 * software developed by the University of California, Berkeley and its
 * contributors'' in the documentation or other materials provided with the
 * distribution and in all advertising materials mentioning features or use
 * of this software.  Neither the name of the University nor the names of
 * its contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* $Header: /home/daffy/u0/vern/flex/RCS/ecs.c,v 2.9 93/12/07 10:18:20 vern Exp $ */

#include "flexdef.h"

/* ccl2ecl - convert character classes to set of equivalence classes */

void ccl2ecl()
	{
	int i, ich, newlen, cclp, ccls, cclmec;

	for ( i = 1; i <= lastccl; ++i )
		{
		/* We loop through each character class, and for each character
		 * in the class, add the character's equivalence class to the
		 * new "character" class we are creating.  Thus when we are all
		 * done, character classes will really consist of collections
		 * of equivalence classes
		 */

		newlen = 0;
		cclp = cclmap[i];

		for ( ccls = 0; ccls < ccllen[i]; ++ccls )
			{
			ich = ccltbl[cclp + ccls];
			cclmec = ecgroup[ich];

			if ( cclmec > 0 )
				{
				ccltbl[cclp + newlen] = cclmec;
				++newlen;
				}
			}

		ccllen[i] = newlen;
		}
	}


/* cre8ecs - associate equivalence class numbers with class members
 *
 * fwd is the forward linked-list of equivalence class members.  bck
 * is the backward linked-list, and num is the number of class members.
 *
 * Returned is the number of classes.
 */

int cre8ecs( fwd, bck, num )
int fwd[], bck[], num;
	{
	int i, j, numcl;

	numcl = 0;

	/* Create equivalence class numbers.  From now on, ABS( bck(x) )
	 * is the equivalence class number for object x.  If bck(x)
	 * is positive, then x is the representative of its equivalence
	 * class.
	 */
	for ( i = 1; i <= num; ++i )
		if ( bck[i] == NIL )
			{
			bck[i] = ++numcl;
			for ( j = fwd[i]; j != NIL; j = fwd[j] )
				bck[j] = -numcl;
			}

	return numcl;
	}


/* mkeccl - update equivalence classes based on character class xtions
 *
 * synopsis
 *    Char ccls[];
 *    int lenccl, fwd[llsiz], bck[llsiz], llsiz, NUL_mapping;
 *    void mkeccl( Char ccls[], int lenccl, int fwd[llsiz], int bck[llsiz],
 *			int llsiz, int NUL_mapping );
 *
 * ccls contains the elements of the character class, lenccl is the
 * number of elements in the ccl, fwd is the forward link-list of equivalent
 * characters, bck is the backward link-list, and llsiz size of the link-list.
 *
 * NUL_mapping is the value which NUL (0) should be mapped to.
 */

void mkeccl( ccls, lenccl, fwd, bck, llsiz, NUL_mapping )
Char ccls[];
int lenccl, fwd[], bck[], llsiz, NUL_mapping;
	{
	int cclp, oldec, newec;
	int cclm, i, j;
	static unsigned char cclflags[CSIZE];	/* initialized to all '\0' */

	/* Note that it doesn't matter whether or not the character class is
	 * negated.  The same results will be obtained in either case.
	 */

	cclp = 0;

	while ( cclp < lenccl )
		{
		cclm = ccls[cclp];

		if ( NUL_mapping && cclm == 0 )
			cclm = NUL_mapping;

		oldec = bck[cclm];
		newec = cclm;

		j = cclp + 1;

		for ( i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i] )
			{ /* look for the symbol in the character class */
			for ( ; j < lenccl; ++j )
				{
				register int ccl_char;

				if ( NUL_mapping && ccls[j] == 0 )
					ccl_char = NUL_mapping;
				else
					ccl_char = ccls[j];

				if ( ccl_char > i )
					break;

				if ( ccl_char == i && ! cclflags[j] )
					{
					/* We found an old companion of cclm
					 * in the ccl.  Link it into the new
					 * equivalence class and flag it as
					 * having been processed.
					 */

					bck[i] = newec;
					fwd[newec] = i;
					newec = i;
					/* Set flag so we don't reprocess. */
					cclflags[j] = 1;

					/* Get next equivalence class member. */
					/* continue 2 */
					goto next_pt;
					}
				}

			/* Symbol isn't in character class.  Put it in the old
			 * equivalence class.
			 */

			bck[i] = oldec;

			if ( oldec != NIL )
				fwd[oldec] = i;

			oldec = i;

			next_pt: ;
			}

		if ( bck[cclm] != NIL || oldec != bck[cclm] )
			{
			bck[cclm] = NIL;
			fwd[oldec] = NIL;
			}

		fwd[newec] = NIL;

		/* Find next ccl member to process. */

		for ( ++cclp; cclflags[cclp] && cclp < lenccl; ++cclp )
			{
			/* Reset "doesn't need processing" flag. */
			cclflags[cclp] = 0;
			}
		}
	}


/* mkechar - create equivalence class for single character */

void mkechar( tch, fwd, bck )
int tch, fwd[], bck[];
	{
	/* If until now the character has been a proper subset of
	 * an equivalence class, break it away to create a new ec
	 */

	if ( fwd[tch] != NIL )
		bck[fwd[tch]] = bck[tch];

	if ( bck[tch] != NIL )
		fwd[bck[tch]] = fwd[tch];

	fwd[tch] = NIL;
	bck[tch] = NIL;
	}
