/*
 Vtext.c - Rintraccia parole scorrette in file
*/

#include <exec/types.h>
#include <ctype.h>
#include <stdio.h>

#ifdef LATTICE          /* Inclusioni per Lattice */
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>
#else
#include <functions.h> /* Inclusione per Aztec C */
#endif

#define MAXLENW  20 /* Massima lunghezza parola + 1 */
#define EX_ERROR  1 /* Ritornato in caso di errore */
#define MINLENW   3 /* Minima lunghezza */
#define VOCALE    1 /* Valore per vocale */
#define CONSON    3 /* Valore per consonante */
static int voci = 1;       /* Numero voci stampate */

static struct nodo {    /* Struttura di un nodo */
char  *parola;     /* Puntatore alla parola */
unsigned conta;    /* Conteggio ricorrenze nel file */
struct nodo *min;  /* Puntatore a nodo precedente */
struct nodo *mag;  /* Puntatore a nodo successivo */
};

void gerror( s, n )   /* Segnalazione di errori ed uscita */
char *s;              /* Punta al testo del messaggio */
int n;                /* Numero di codice di errore */
{
 fprintf(stderr,"\nErrore %d: %s\n",n,s);
 exit( EX_ERROR );
}

/* Alloca memoria per un nuovo nodo */
struct nodo *palloc()
{
 char *malloc();
 return((struct nodo *)malloc(sizeof(struct nodo)));
}

/* Alloca memoria e salva una parola nuova */
char *savestr( s )  
char *s;
{
 char *p;

 p = (char *) malloc( strlen( s ));
 if ( p == NULL ) 
   return( p );
 else
   return( (char *)strcpy( p, s) );
}

/* Stampa ricorsivamente l'albero */
void displyalbero(p)
struct nodo *p;
{
 if ( p != NULL )
 {
   displyalbero( p -> min );
   if ( p -> conta == 1)
     {
     printf("%5d -: %-15s", voci, p -> parola);
     if ( !( voci++ % 3) )
       printf("\n");
     }
   displyalbero( p -> mag );
 }
}

/* Inserisce un nuovo elemento nell'albero */
struct nodo *insert( p, w ) 
struct nodo *p; char *w;
{
 register short c;

 if ( p == NULL )
 { /* Nuova parola */
 if ( ( p = palloc() ) == NULL )
   gerror("Non riesco ad allocare RAM per il nodo!",1);

   p -> parola = savestr( w );
   p -> conta  = 1;
   p -> min = p -> mag = NULL;
 }
 else if (( c = strcmp(w,p->parola)) == 0 ) /* Parola ripetuta */
   p -> conta++;                           /* Incrementa conto */
 else if ( c < 0 )
   p -> min = insert( p -> min, w ); /* Inserisce prima */
 else
   p -> mag = insert( p -> mag, w ); /* Inserisce dopo */
 return(p);
}

/* Legge una stringa accettabile dal file */
char *getword( s, n, infile )
char *s; /* Converte in minuscolo e ritorna in s */
short n;
FILE *infile;
{
 register char c, *cs;
 cs = s;
 while ( --n > 0 && ( c = getc(infile) ) != EOF ) {
   if ( (c = tolower(c)) < 'a' || c > 'z' )
     break;
   else
     *cs++ = c;
 }
 *cs = NULL;
 return( ( c == EOF && cs == s ) ? NULL : s );
}

BOOL vocale( c ) /* Ritorna TRUE se vocale */
char c;
{
 if ( c=='e' || c=='i' || c=='a' || c=='o' || c=='u' )
   return( TRUE );
 return( FALSE );
}


/* Verifica correttezza di una parola (TRUE/FALSE) */
BOOL checkw( w )
char *w;
{
unsigned short i, c, flag1 = 0, flag2 = 0;

 for ( i = 0 ; i < strlen( w )-1 ; i++ )
 {
   if ( ( c = vocale(*(w+i)) ) == vocale(*(w+i+1)) )
   {
     if ( c == TRUE )
       {                            /* Doppia vocale */
          if ( *(w+i) == *(w+i+1) )
            return( FALSE );        /* Sono uguali */
          else if ( ++flag2 == 2 )
            return( FALSE );        /* 3 vocali di fila */
       } 
     else                           /* Tripla consonante */
       if ( ++flag1 == 2 )
         return( FALSE );
   }
     else flag1 = flag2 = 0;
 }                                  /* fine del for() */
 return( TRUE );
}

void main(argc,argv)
int argc;
char *argv[];
{
struct nodo *palloc(), *insert(), *first = NULL;
char item[MAXLENW+1],  *savestr(), *getword();

FILE *fopen(), *infile;
LONG countword = 0;
void gerror(), displyalbero();

 if ( argc != 2 )
   gerror("Uso: Vtext nomefile",0);

 if ( ( infile = fopen(argv[1],"r")) == NULL )
   gerror("Non si apre il file di input!",2);

 printf("\nScansione del file \033[1m%s\033[0m\n\n", argv[1]);

 while ( getword( item, MAXLENW, infile ) != NULL )
    if ( strlen(item) >= MINLENW && checkw(item) == FALSE )
    {
      first = insert(first,item);
      ++countword;
    }

displyalbero( first );
printf("\n\nFinito, memorizzate %ld parole.\n\n",countword);
fclose( infile );
}
