h42836
s 00012/00004/00457
d D 1.5 80/09/10 12:56:25 lcd 5 4
c Fixed label search bug in labsiz.
e
s 00006/00000/00455
d D 1.4 80/09/09 16:05:20 lcd 4 3
c Fixed runaway bug
e
s 00002/00002/00453
d D 1.3 80/05/16 11:26:24 lcd 3 2
c uncommented print out on name find
e
s 00048/00037/00407
d D 1.2 80/05/16 10:53:22 lcd 2 1
c Fixed string equal problem ... kludged it!
e
s 00444/00000/00000
d D 1.1 80/05/15 14:27:11 lcd 1 0
e
u
sunix
lcd
U
t
T
I 1
#

#include "globals.h"
#include <stdio.h>

/*
 *	modsym.c: do Modula symbol search in a.lst
 */

CONST	char	*_S_msym	"%W%";

#define ALPHASIZE       256
#define NOOC		'-'	/* DEBUG should be eos */

#define STRINGLEN	512

VAR	integer	delta1[ ALPHASIZE ];
	integer delta2[ MAXLINELENGTH ];
	integer	large;

	integer	patlen;
	integer strlen;
	integer	patoff;
	char	Mline[ STRINGLEN ];
	boolean	EndOfFile;


/*
 *	getMline: gets next Mline for scanner
 */

PROCEDURE integer getMline()

BEGIN	VAR	integer	index;
		integer readch;

	EndOfFile = false;
	index = 0;

	LOOP	readch = getc( o_alst );
		
		IF readch == EOF
		THEN	readch = eoln;
			EndOfFile = true;
		END;

		Mline[ index ] = readch;

		WHEN Mline[ index ] == eoln DO EXIT;

		inc( index );
	END;

	Mline[ index ] = eos;
	return( index );
END

/*
 *	gosrch: do fast search algorithm
 */

PROCEDURE integer gosrch( pat )

VAR	char	*pat;

BEGIN	VAR	integer	i;
		integer j;
		integer tmp;
		integer result;
		boolean brk;

	result = STRINGLEN;
	brk = false;
	i = patlen;

D 2
	LOOP	tmp = delta1[ Mline[ i-1 ]&0377 ];
		i = i+tmp;
E 2
I 2
	/* when patlen = strlen there is a bug here */
E 2

D 2
		/*	printf("f%d ",i);	*/
		/*	printf("%d %d\n",i,strlen);	*/
E 2
I 2
	IF patlen < strlen
	THEN	LOOP	tmp = delta1[ Mline[ i-1 ]&0377 ];
			i = i+tmp;
E 2

D 2
		IF i > strlen
		THEN	WHEN i <= large DO EXIT;
E 2
I 2
			/*	printf("f%d ",i);	*/
			/*	printf("%d %d\n",i,strlen);	*/
E 2

D 2
			/* 	printf("u%d ",i); */
E 2
I 2
			IF i > strlen
			THEN	WHEN i <= large DO EXIT;
E 2

D 2
			i = ( i-large )-1;
			j = patlen-1;
E 2
I 2
				/*	printf("u%d ",i);	*/
E 2

D 2
			LOOP	WHEN ( j == 0 )
				DO	result = i;
					brk = true;
				EXIT;
E 2
I 2
				i = ( i-large )-1;
				j = patlen-1;
E 2

D 2
				WHEN ( i < 1 ) OR ( i > strlen ) DO EXIT;
E 2
I 2
				LOOP	WHEN ( j == 0 )
					DO	result = i;
						brk = true;
					EXIT;

					WHEN ( i < 1 ) OR ( i > strlen ) DO EXIT;
E 2
				 
D 2
				/*	printf("s%d ",j); */
E 2
I 2
					/*	printf("s%d ",j);	*/
E 2

D 2
				IF Mline[ i-1 ] == pat[ j-1 ]
				THEN	dec( j );
					dec( i );
				ELSE	tmp = delta1[ Mline[ i-1 ]&0377 ];
E 2
I 2
					IF Mline[ i-1 ] == pat[ j-1 ]
					THEN	dec( j );
						dec( i );
					ELSE	tmp = delta1[ Mline[ i-1 ]&0377 ];
E 2
					
D 2
					IF tmp == large 
					THEN	tmp = 0;
					END;
E 2
I 2
						IF tmp == large 
						THEN	tmp = 0;
						END;
E 2

D 2
					IF tmp < delta2[ j-1 ]
					THEN	tmp = delta2[ j-1 ];
					END;
E 2
I 2
						IF tmp < delta2[ j-1 ]
						THEN	tmp = delta2[ j-1 ];
						END;
E 2

D 2
					i = i+tmp;
					WHEN true DO EXIT;
E 2
I 2
						i = i+tmp;
						WHEN true DO EXIT;
					END;
E 2
				END;
D 2
			END;
E 2

D 2
			WHEN brk DO EXIT;
E 2
I 2
				WHEN brk DO EXIT;
			END;
E 2
		END;
	END;

	return( result );
END




/*
 *	unify: tests to see if the two strings unify
 */

PROCEDURE unify( s1, s2, len )

VAR	char	s1[];
	char	s2[];
	integer len;

BEGIN	VAR	integer	index;
		boolean	result;
		boolean atend;

	atend = false;

	index = 0;
	LOOP	WHEN index == len
		DO	result = true;
		EXIT;

		IF s2[ index ] != NOOC
		THEN	atend = true;
		END;

		WHEN ( s1[ index ] != s2[ index ] ) AND
		     ( ( NOT ( ( s1[ index ] == NOOC ) OR
			       ( s2[ index ] == NOOC ) ) ) OR atend )
		DO	result = false;
		EXIT;

		inc( index );
	END;

D 2
	/*	printf("Unify: %s %s %s\n",s1,s2,result? "TRUE":"FALSE" ); */
E 2
I 2
	/*	printf("Unify: %s %s %s\n",s1,s2,result? "TRUE":"FALSE" );	*/
E 2
	return( result );
END


/*
 *	cpystr: copy and make of string for unify test
 */

PROCEDURE cpystr( pat, from, to, word, patlen )

CONST	char	pat[];
	integer	from;
	integer to;
	integer	patlen;
VAR	char	word[];


BEGIN	VAR	integer	f;
		integer	t;
		integer w;

	f = from-1;
	t = to-1;
	w = 0;

	LOOP	WHEN ( f > t )
		DO EXIT;

		IF ( f < 0 ) OR
		   ( f >= patlen )
		THEN	word[w] = NOOC;
		ELSE	word[w] = pat[f];
		END;

		inc( w );
		inc( f );
	END;

	word[w] = eos;		/* DEBUG */
END


/*
 *	delsetup: delta1 and delta2 setup
 */

PROCEDURE delsetup( pat )

CONST	char	*pat;

BEGIN	VAR	integer index;
		integer	i;
		integer j;
		integer k;
		integer	delta;
		char	w1[ MAXLINELENGTH ];
		char	w2[ MAXLINELENGTH ];

	patlen = size( pat ) -1;

	index = 0;
	WHILE index < ALPHASIZE
	DO	delta1[ inc( index ) ] = patlen;
	END;

	j = patlen;
	WHILE j > 0
	DO	delta = pat[ j-1 ]&0377;

		IF delta1[ delta ] == patlen
		THEN	delta1[ delta ] = patlen-j;
		END;

		dec( j );
	END;

	index = 0;
	WHILE index < patlen
	DO	delta2[ inc( index ) ] = 0;
	END;

	j = 1;
	WHILE j <= patlen
	DO	k = patlen;

		LOOP	cpystr( pat, j+1, patlen, w1, patlen );
			cpystr( pat, k, k+patlen-j-1, w2, patlen );

			/*	printf("%d",k);	*/
			WHEN unify( w1, w2, patlen-j ) AND
			   ( ( k <= 1 ) OR
			     ( pat[ k-2 ] != pat[ j-1 ] ) )
			DO EXIT;

			dec( k );
		END;

		/*	putchar( eoln );	*/
		delta2[ j-1 ] = patlen+1-k;
		inc( j );
	END;
END

/*
 *	search: search a.lst for pattern
 */

PROCEDURE integer search( pat )

CONST	char	*pat;

BEGIN	VAR	integer	result;
		boolean	brk;
I 2
		integer	count;
E 2

I 4
	IF pat[0] == eos
	THEN	return( STRINGLEN );
	END;

E 4
	fseek( o_alst, 0L, 0 );

	delsetup( pat );

	result = STRINGLEN;

I 2
	count = 0;

E 2
	LOOP	strlen = getMline();

		WHEN EndOfFile DO EXIT;

I 2
		inc( count );
		/*	printf("L%d ", count );	*/

E 2
		IF strlen != 0
		THEN	large	= strlen+patlen+10;
			delta1[ pat[ patlen-1 ]&0377 ] = large;

D 2
			result = gosrch( pat );
E 2
I 2
			IF ( Mline[0] == 'P' ) OR
			   ( Mline[0] == 'V' ) OR
			   ( ( Mline[0] == 'C' ) AND ( Mline[1] == 'O' ) )
			THEN	result = gosrch( pat );
			END;
E 2

D 2
			WHEN ( result != STRINGLEN ) AND
			      ( ( Mline[0] == 'P' ) OR
				( Mline[0] == 'V' ) OR
			      	( ( Mline[0] == 'C' ) AND ( Mline[1] == 'O' ) ) )
E 2
I 2
			WHEN result != STRINGLEN
E 2
			DO EXIT;
		END;
	END;
I 4

	return( result );
E 4
END

/*
 *	strfnd: look for the pattern in the current Mline
 */

PROCEDURE integer strfnd( pat )

CONST	char	*pat;

BEGIN	delsetup( pat );

	large = strlen+patlen+10;

	return( gosrch( pat ) );
END

/*
 *	xtctd: extract decimal number
 */

PROCEDURE xtctd( word, sze )

CONST	char	*word;
VAR	long	*sze;

BEGIN	VAR	integer	index;
		integer	itmp;

	*sze = 0L;
	index = 0;

	LOOP	WHEN ( word[ index ] < '0' ) OR
		     ( word[ index ] > '9' )
		DO EXIT;

		itmp = word[index] - '0';

		*sze = ( *sze*10L ) + itmp;
		inc( index );
	END;
END


/*
 *	labsiz: get label and size of an object
 */

PROCEDURE boolean labsiz( lab, lnam, sze )

VAR	char	*lab;
	char	*lnam;
	long	*sze;

BEGIN	VAR	integer findi;
		integer i1;
		integer	i2;

	
	findi = search( lab );		/* search for string */

	IF findi == STRINGLEN
	THEN	return( false );
	ELSE	i1 = findi;

I 5
		LOOP	WHEN ( Mline[ i1 ] == '\t' ) OR
			     ( i1 == strlen )
			DO EXIT;

			inc( i1 );
		END;

E 5
		LOOP	WHEN ( i1 == strlen ) OR
			     ( Mline[ i1 ] == 'L' ) OR
			     ( Mline[ i1 ] == 'G' )
			DO EXIT;

			inc( i1 );
		END;

D 5
		IF i1 > strlen
E 5
I 5
		IF i1 >= strlen
E 5
		THEN	return( false );

		ELSE	i2 = 0;

			LOOP	WHEN ( i1 == strlen ) OR
				     ( Mline[ i1 ] == 'B' )
				DO EXIT;

				lnam[ i2 ] = Mline[ i1 ];

				inc( i1 );
				inc( i2 );
			END;

			IF i1 == strlen
			THEN	return( false );

			ELSE	lnam[ i2 ]= eos;

				LOOP	WHEN ( i1 == strlen ) OR
					     ( Mline[ i1 ] == ':' )
					DO EXIT;

					inc( i1 );
				END;

				IF i1 == strlen
				THEN	*sze = 0L;
				ELSE	xtctd( &Mline[i1+1], sze );
				END;

				return( true );
			END;
		END;
	END;
END

/*
 *	fndlab: look for the label associated with the pattern
 */

PROCEDURE fndlab()

BEGIN	VAR	char	word[ MAXLINELENGTH ];
		char	pat[ MAXLINELENGTH ];
		long	sze;

	getword( pat );

	IF labsiz( pat, word, &sze )
D 2
	THEN	printf("%s\n", Mline );
E 2
I 2
D 3
	THEN	/*	printf("%s\n", Mline );	*/
E 3
I 3
	THEN	printf("%s\n", Mline );
E 3
E 2
		dislabel( word );
D 2
	ELSE	printf("?\n");
E 2
I 2
D 3
	ELSE	/*	printf("?\n");	*/
E 3
I 3
	ELSE	printf("?\n");
E 3
E 2
	END;
END

/*
 *	getladdr: get address and size of label
 */

PROCEDURE getladdr( word, addrs, sze )

CONST	char	*word;
VAR	long	*addrs;
	long	*sze;

BEGIN	VAR	char	lab[ MAXLINELENGTH ];

D 5
	labsiz( word, lab, sze );

	getaddr( lab, addrs );
E 5
I 5
	IF labsiz( word, lab, sze )
	THEN	getaddr( lab, addrs );
	ELSE	printf("?\n");
	END
E 5
END
E 1
