/*
  Functions used by Dialog Manager to map parse output.
  All functions assume that the "parse" parameter points to a text string
  output by the parser.

*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "parse.h"
#include "dm.h"

#define	TRUE	1
#define	FALSE	0

extern char	*pstr_buf_ptr,
		*pstr_buf_end;
extern int	StringBufSize;

char *extract_string(char *s);
//char *extract_string();
char *extract_name(char *s);
//char *extract_name();

/* TRUE if slot "name" occurs in "parse", FALSE otherwise */
int CheckOnSlot(char *name, char *parse) {
    char	*s;

    for(s= parse; *s; s++)  if( !scmp(name,s) ) return(TRUE);
    return(FALSE);
}

/* TRUE if NetName occurs in SlotName in "parse", FALSE otherwise */
int CheckOnNet(char *NetName, char *SlotName, char *parse) {
    char	*s;
    int		paren;

    for(s= parse; *s; s++)  if( !scmp(SlotName,s) ) break;
    if( !*s ) return(FALSE);

    /* scan for '(' */
    for( ; *s && (*s != '('); s++);
    if( !*s ) return(FALSE);

    for( paren= 1, s++; *s; s++) {
	if( *s == '(' ) {
	    paren++;
	    continue;
	}
	if( *s == ')' ) if( !--paren ) return(FALSE);
	if( !scmp(NetName,s) ) return(TRUE);
    }
    return(FALSE);
}

/* return number of slots in parse */
int GetNumberOfSlots(char *parse) {
    char	*s;
    int		paren,
		num_slots;

    num_slots= 0;
    for(s= parse; *s; s++) {

	/* scan for start of slot */
	for( ; *s && (*s != '['); s++);
	if( !*s ) return(num_slots);
	num_slots++;

	/* scan for '(', open paren for slot */
	for( s++; *s && (*s != '('); s++);
	if( !*s ) return(num_slots);

	for( paren= 1, s++; *s; s++) {
	    if( *s == '(' ) { paren++; continue; }
	    if( *s == ')' ) if( !--paren ) break;
	}
    }
    return(num_slots);
}

/* return number of nets in slot in parse */
int GetNumberOfNets(int slot_num, char *parse) {
    char	*s;
    int		paren,
		num_slots,
		num_nets;

    num_nets= 0;
    /* find start of slot */
    for(s= parse, num_slots= 0; *s; s++) {

	/* scan for start of slot */
	for( ; *s && (*s != '['); s++);
	if( !*s ) return(num_nets);
	if(num_slots++ == slot_num) break;

	/* scan for '(', open paren for slot */
	for( s++; *s && (*s != '('); s++);
	if( !*s ) return(num_nets);

	for( paren= 1, s++; *s; s++) {
	    if( *s == '(' ) { paren++; continue; }
	    if( *s == ')' ) if( !--paren ) break;
	}
    }
    if( *s != '[' ) return(num_nets);

    /* scan for '(', open paren for slot */
    for( s++; *s && (*s != '('); s++);
    if( !*s ) return(num_nets);
    num_nets= 1;

    for( paren= 1, s++; *s; s++) {
	if( *s == '[' ) { num_nets++; continue; }
	if( *s == '(' ) { paren++; continue; }
	if( *s == ')' ) if( !--paren ) break;
    }
    return(num_nets);
}

/* return name of slot in parsed frame indicated by slot_num */
char *GetSlotNameByNumber(int slot_num, char *parse, Gram *gram) {
  char	*s;
  //char name[LABEL_LEN];
  int paren;
  int num_slots;
  //int idx;
  
    /* find start of slot */
    for(s= parse, num_slots= 0; *s; s++) {

	/* scan for start of slot */
	for( ; *s && (*s != '['); s++);
	if( !*s ) return(0);
	if(num_slots++ == slot_num) break;

	/* scan for '(', open paren for slot */
	for( s++; *s && (*s != '('); s++);
	if( !*s ) return(0);

	for( paren= 1, s++; *s; s++) {
	    if( *s == '(' ) { paren++; continue; }
	    if( *s == ')' ) if( !--paren ) break;
	}
    }
    if( *s != '[' ) return(0);
    return(extract_name(s));
}

/* return substring associated with slot given by slot_num */
char *GetSlotResultByNumber(int slot_num, char *parse) {
    char	*s;
    int		paren,
		num_slots;

    /* find start of slot */
    for(s= parse, num_slots= 0; *s; s++) {

	/* scan for start of slot */
	for( ; *s && (*s != '['); s++);
	if( !*s ) return(0);
	if(num_slots++ == slot_num) break;

	/* scan for '(', open paren for slot */
	for( s++; *s && (*s != '('); s++);
	if( !*s ) return(0);

	for( paren= 1, s++; *s; s++) {
	    if( *s == '(' ) { paren++; continue; }
	    if( *s == ')' ) if( !--paren ) break;
	}
    }

    if( *s != '[' ) return(0);

    return(extract_string(s));
}

/* return substring associated with slot given by slot_name */
char *GetSlotResultByName(char *slot_name, char *parse) {
    char	*s;
    int		paren;

    /* find start of slot */
    for(s= parse; *s; s++) {

	/* scan for start of slot */
	for( ; *s && (*s != '['); s++);
	if( !*s ) return(0);
	if(!scmp(slot_name,s+1)) break;

	/* scan for '(', open paren for slot */
	for( s++; *s && (*s != '('); s++);
	if( !*s ) return(0);

	for( paren= 1, s++; *s; s++) {
	    if( *s == '(' ) { paren++; continue; }
	    if( *s == ')' ) if( !--paren ) break;
	}
    }

    if( *s != '[' ) return(0);

    return(extract_string(s));
}

/* return name of net referenced by net number and slot number */
char *GetNetNameByNumber(int net_num, int slot_num, char *parse, Gram *gram) {
  char	*s;
  //char name[LABEL_LEN];
  int paren;
  int num_slots;
  //int idx;
  int num_nets;

    /* find start of slot */
    for(s= parse, num_slots= 0; *s; s++) {

	/* scan for start of slot */
	for( ; *s && (*s != '['); s++);
	if( !*s ) return(0);
	if(num_slots++ == slot_num) break;

	/* scan for '(', open paren for slot */
	for( s++; *s && (*s != '('); s++);
	if( !*s ) return(0);

	for( paren= 1, s++; *s; s++) {
	    if( *s == '(' ) { paren++; continue; }
	    if( *s == ')' ) if( !--paren ) break;
	}
    }
    if( *s != '[' ) return(0);

    for(num_nets=-1, paren= 0; *s; s++) {
	if( *s == '[' ) { if( ++num_nets == net_num ) break; continue; }
	if( *s == '(' ) { paren++; continue; }
	if( *s == ')' ) if( !--paren ) break;
    }
    if( num_nets != net_num ) return(0);
    return(extract_name(s));
}


/* return name of net referenced by net number and slot number */
char *GetNetResultByNumber(int net_num,
			   int slot_num, char *parse, Gram *gram) {
    char	*s;
    int		paren,
		num_slots,
		num_nets;

    /* find start of slot */
    for(s= parse, num_slots= 0; *s; s++) {

	/* scan for start of slot */
	for( ; *s && (*s != '['); s++);
	if( !*s ) return(0);
	if(num_slots++ == slot_num) break;

	/* scan for '(', open paren for slot */
	for( s++; *s && (*s != '('); s++);
	if( !*s ) return(0);

	for( paren= 1, s++; *s; s++) {
	    if( *s == '(' ) { paren++; continue; }
	    if( *s == ')' ) if( !--paren ) break;
	}
    }
    if( *s != '[' ) return(0);

    /* find start of net */
    for(num_nets=-1, paren= 0; *s; s++) {
	if( *s == '[' ) { if( ++num_nets == net_num ) break; continue; }
	if( *s == '(' ) { paren++; continue; }
	if( *s == ')' ) if( !--paren ) break;
    }
    if( num_nets != net_num ) return(0);

    return(extract_string(s));
}

/* return name of net referenced by net name and slot name */
char *GetNetResultByName(char *net_name,char *slot_name,
			 char *parse, Gram *gram) {
    char	*s;
    int		paren;

    /* find start of slot */
    for(s= parse; *s; s++) {

	/* scan for start of slot */
	for( ; *s && (*s != '['); s++);
	if( !*s ) return(0);
	if(!scmp(slot_name,s+1)) break;

	/* scan for '(', open paren for slot */
	for( s++; *s && (*s != '('); s++);
	if( !*s ) return(0);

	for( paren= 1, s++; *s; s++) {
	    if( *s == '(' ) { paren++; continue; }
	    if( *s == ')' ) if( !--paren ) break;
	}
    }
    if( *s != '[' ) return(0);

    /* find start of net */
    for(paren= 0; *s; s++) {
	if( *s == '[' ) { if(!scmp(net_name,s+1)) break; continue; }
	if( *s == '(' ) { paren++; continue; }
	if( *s == ')' ) if( !--paren ) break;
    }
    if( !*s ) return(0);
    if( !paren ) return(0);

    return(extract_string(s));
}


int isword(char s) {
    switch(s) {
	case '(':
	case ')':
	case '[':
	case ']':
	case ' ':
			return(0);
	default:	return(1);
    }
}

char *extract_string(char *s) {
    char *f, *t;
    int	paren;

    /* scan for '(', open paren for slot */
    for( s++; *s && (*s != '('); s++);
    if( !*s ) return(0);

    f=t= pstr_buf_ptr;
    for( paren= 1, s++; *s; s++) {
	if( *s == ' ' )  continue;
	if( *s == '(' ) { paren++; continue; }
	if( *s == ')' ) if( !--paren ) break;
	if( *s == '[' ) { 
	    while(*s && (*s != ']') ) s++;
	    s++;
	}
	else {
	    while( isword(*s) ) *t++= *s++;
	    if( t >= pstr_buf_end ) {
		fprintf(stderr,"StringBufSize overflow, = %d\n", StringBufSize);
		return(0);
	    }
	    *t++= ' ';
	}
    }
    *(t-1)= 0;
    pstr_buf_ptr= t;
    return(f);
}

char *extract_name(char *s) {
    char *f, *t;

    f=t= pstr_buf_ptr;
    for( s++; *s && (*s != ']'); s++) {
	if( t >= pstr_buf_end ) {
	    fprintf(stderr,"StringBufSize overflow, = %d\n", StringBufSize);
	    return(0);
	}
	*t++= *s;
    }
    *t++= 0;
    pstr_buf_ptr= t;
    return(f);
}
