/*

passi3.c

*/

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

#include "italiane.h"

#define TRIP(a,b,c) ( (ULONG)(0)<<24L | (ULONG)(a)<<16L | (ULONG)(b)<<8 | (c) )
#define NTRIP 11L           /* numero triplette nella tavola tmTab */
#define N_ECC 8L            /* numero triplette nella tavola tmEcc */

#define NEWLINE   13
#define SPAZIO    32
#define PUNTO     46        /* ASCII  .  */

#define ACCENTO   96        /* ASCII  `  */
#define APOSTROFO 39        /* ASCII  '  */
#define I_ACC     1         /* indice colonna triplette accento */
#define I_APO     2         /* indice colonna triplette apostrofo */

#define L3_AND 0x000000ff
#define L2_AND 0x0000ff00
#define L1_AND 0x00ff0000

#define L2_SHF 8
#define L1_SHF 16L

                                /* tavola lookup delle triplette notevoli */
static ULONG  tmTab[NTRIP][3];  /*  tm_ : ungherese per Tavola a Matrice */
static ULONG  tmEcc[N_ECC][2];  /* tavola parole tronche */
static UBYTE *pIb;              /* puntatore al buffer, per praticita` */
static long   Len;              /* lunghezza del buffer corrente */
static long   Count;            /* contatore scansione buffer */
static UBYTE  Cur, Prev, Next;  /* carattere Prevedente e processando */
static BOOL   fQuote;           /* flag di presenza apostrofo dispari */
static ULONG  Triplet;          /* tripletta (come in IFF Chunks) */
static ULONG  TripFound;        /* indice matrice triplette */


/*
    ISPUNT: Versione privata e limitata di ispunct
*/

BOOL ISPUNT( Ch )
UBYTE Ch;

{
BOOL fValue;

switch( Ch ) {
    case '.' :
    case ',' :
    case ':' :
    case ';' :
    case '!' :
    case '?' :
    case ')' :
    case '>' :
        fValue = TRUE;
        break;

    default :
        fValue = FALSE;

} /* switch */

return fValue;
} /* Fine di ISPUNT */

/*-------------------------------------------------------------------
    ECCEZIONE: Valuta la tripletta corrente e decide sulle eccezioni.
        Elenco tronche riconosciute:
            be', ca', mo', po', te', to', ve'
*/

void ECCEZIONE()

{
BOOL  fValue;               /* valore di ritorno della funzione */
long  cTemp;                /* contatore temporaneo */
UBYTE CurL, PrevL, NextL;   /* copia per una tripletta Locale */
ULONG TripL;                /* tripletta Locale destinata alle eccezioni */
ULONG itmEcc;               /* contatore indice matrice triplette */

fValue = FALSE;
cTemp = Count - 1;  /* perche il contatore e` su: ' o su: ` */

if ( ( *(pIb + (Count-3) ) ) != 32 ) {
    Triplet = tmTab[ TripFound ][ 0 ];
    return;
} /* if se non e` una parola: " __' ", come " po' ", " be' "*/

/* ora che siamo sicuri, facciamo la tripletta sulla vocale */

PrevL = *(pIb + (cTemp-1) );
CurL  = *(pIb + cTemp);         /* cTemp e` sulla vocale */
NextL = *(pIb + (cTemp+1) );

TripL = TRIP( PrevL, CurL, NextL );

for( itmEcc = 1L ; itmEcc < N_ECC ; itmEcc++ ) {
    if ( TripL == tmEcc[ itmEcc ][ 1 ] ) {
        Triplet = tmEcc[ itmEcc ][ 0 ];
        return;
    } /* if */
} /* for */

Triplet = tmTab[ TripFound ][ 0 ];      /* tmTab, regolare! */

} /* Fine di ECCEZIONE */

/*-----------------------------------------------------------
    FILTRA_2: Esegue la valutazione e l'eventuale filtratura.
*/

void FILTRA_2( iSrc )
int iSrc;             /* indice colonna sorgente tmTab */

{
UBYTE TmpNext = 0;
ULONG itmTab;           /* contatore indice matrice triplette */

if ( ISPUNT( Next ) ) {
    TmpNext = Next;
    Next = PUNTO;
} /* if */

Triplet = TRIP( Prev, Cur, Next );  /* codifica la tripletta */
TripFound = 0L;

for( itmTab = 1L ; itmTab < NTRIP ; itmTab++ ) {
    if ( Triplet == tmTab[ itmTab ][ iSrc ] ) {
        TripFound = itmTab;     /* altrimenti TripFound resta a 0... */
        break;
    } /* if */
} /* for */

if ( TripFound == 0L ) {
    fQuote = FALSE;
    return;                     /* ...e si torna senza azione */
} /* if */

/* LA TRIPLETTA E` DEGNA DI NOTA: */

    if ( iSrc == I_APO) {
        if ( fQuote ) {
            fQuote = FALSE;         /* non filtra e chiude l'inciso */
        }                               /* if fQuote */
        else {
            ECCEZIONE();
        }                               /* else fQuote */
    }                               /* if iSrc == I_APO */
    else {
        Triplet = tmTab[ TripFound ][ 0 ];
    }                               /* else iSrc == I_APO */

Next = (UBYTE)( Triplet & L3_AND );
Cur  = (UBYTE)( ( Triplet & L2_AND ) >> L2_SHF );
Prev = (UBYTE)( ( Triplet & L1_AND ) >> L1_SHF );

*(pIb + (Count-1) ) = Prev;
*(pIb + Count )     = ( (TmpNext) ? TmpNext : Cur );
*(pIb + (Count+1) ) = Next;

} /* Fine di FILTRA_2 */

/*-----------------------------------------------------------
    PASSO_2: Esegue il secondo passo di analisi e filtratura.
*/

void PASSO_2( p )
BUFD *p;

{
ULONG Tripsup;          /* tripletta di supporto */

TripFound = 0L;

for( Count = 1 ; Count < (Len - 1) ; Count++ ) {

    Prev = *(pIb + (Count-1) );
    Cur  = *(pIb + Count);
    Next = *(pIb + (Count+1) );

    switch( Cur ) {
        case ACCENTO :
        case APOSTROFO :
            if ( (Prev == NEWLINE) || (isspace( Prev )) )
                fQuote = !fQuote;   /* qui pensa inizio inciso */
            else
                FILTRA_2( ( (Cur == ACCENTO) ? I_ACC : I_APO ) );
            break;

        case PUNTO :
            if ( ( Next == NEWLINE ) || (isspace( Next ) ) )
                fQuote = FALSE;     /* un reset per evitare propagazioni */
            break;

        case NEWLINE :
            fQuote = FALSE;
            break;

        default :
            break;

    } /* switch */
} /* for */

} /* Fine di PASSO_2 */

/*--------------------------------------------------------
    PASSI: (MAIN) Esegue i passi di conversione necessari.
    ------------------------------------------------------
*/

void PASSI( pBp )
BUFD *pBp;

{
/*  TAVOLA DELLE TRIPLETTE NOTEVOLI  */

tmTab[0][0] = 0L; tmTab[0][1] = 0L; tmTab[0][2] = 0L;   /* conteggia da 1 */

tmTab[ 1][0] = TRIP( 224, 32, 32 );  /* all'indice 0 il risultato */
tmTab[ 2][0] = TRIP( 232, 32, 32 );
tmTab[ 3][0] = TRIP( 236, 32, 32 );
tmTab[ 4][0] = TRIP( 242, 32, 32 );
tmTab[ 5][0] = TRIP( 249, 32, 32 );
tmTab[ 6][0] = TRIP( 224, 46, 32 );
tmTab[ 7][0] = TRIP( 232, 46, 32 );
tmTab[ 8][0] = TRIP( 236, 46, 32 );
tmTab[ 9][0] = TRIP( 242, 46, 32 );
tmTab[10][0] = TRIP( 249, 46, 32 );

tmTab[ 1][1] = TRIP(  97, 96, 32 );  /* triplette per  `  */
tmTab[ 2][1] = TRIP( 101, 96, 32 );
tmTab[ 3][1] = TRIP( 105, 96, 32 );
tmTab[ 4][1] = TRIP( 111, 96, 32 );
tmTab[ 5][1] = TRIP( 117, 96, 32 );
tmTab[ 6][1] = TRIP(  97, 96, 46 );
tmTab[ 7][1] = TRIP( 101, 96, 46 );
tmTab[ 8][1] = TRIP( 105, 96, 46 );
tmTab[ 9][1] = TRIP( 111, 96, 46 );
tmTab[10][1] = TRIP( 117, 96, 46 );

tmTab[ 1][2] = TRIP(  97, 39, 32 );  /* triplette per  '  */
tmTab[ 2][2] = TRIP( 101, 39, 32 );
tmTab[ 3][2] = TRIP( 105, 39, 32 );
tmTab[ 4][2] = TRIP( 111, 39, 32 );
tmTab[ 5][2] = TRIP( 117, 39, 32 );
tmTab[ 6][2] = TRIP(  97, 39, 46 );
tmTab[ 7][2] = TRIP( 101, 39, 46 );
tmTab[ 8][2] = TRIP( 105, 39, 46 );
tmTab[ 9][2] = TRIP( 111, 39, 46 );
tmTab[10][2] = TRIP( 117, 39, 46 );

/*  TAVOLA DELLE TRIPLETTE ECCEZIONI (PAROLE TRONCHE) */

tmEcc[0][0] = 0L; tmEcc[0][1] = 0L;

tmEcc[1][1] = TRIP('c','a',39); tmEcc[1][0] = TRIP( 97,39,32);
tmEcc[2][1] = TRIP('b','e',39); tmEcc[2][0] = TRIP(101,39,32);
tmEcc[3][1] = TRIP('t','e',39); tmEcc[3][0] = TRIP(101,39,32);
tmEcc[4][1] = TRIP('v','e',39); tmEcc[4][0] = TRIP(101,39,32);
tmEcc[5][1] = TRIP('m','o',39); tmEcc[5][0] = TRIP(111,39,32);
tmEcc[6][1] = TRIP('p','o',39); tmEcc[6][0] = TRIP(111,39,32);
tmEcc[7][1] = TRIP('t','o',39); tmEcc[7][0] = TRIP(111,39,32);

Len = pBp->bd_len;
pIb  = (UBYTE *)pBp->bd_buf;
fQuote = FALSE;

PASSO_2( pBp );
} /* Fine di PASSI */
