v20i055: notation - chess text handler, Part04/04

Henry Thomas hthomas at irisa.fr
Mon Jun 17 15:17:04 AEST 1991


Submitted-by: Henry Thomas <hthomas at irisa.fr>
Posting-number: Volume 20, Issue 55
Archive-name: notation/part04
Supersedes: notation: Volume 18, Issue 12-14

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 4)."
# Contents:  notation.c
# Wrapped by hthomas at cattus on Sun Jun 16 18:17:28 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'notation.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'notation.c'\"
else
echo shar: Extracting \"'notation.c'\" \(40751 characters\)
sed "s/^X//" >'notation.c' <<'END_OF_FILE'
X/*
X  Notation program
X  @(#)notation.c	3.1 (C) Henry Thomas\tVersion 3.1\tDated 6/16/91
X */
X/* Programme d'analyse de notation echiquienne
X   Copyright (C) 1990 Henry Thomas
X   Nom: notation
X   Auteur: Henry Thomas
X   Date: 27/11/90
X/*
XThis file is part of NOTATION program.
X
XNOTATION is free software; you can redistribute it and/or modify
Xit under the terms of the GNU General Public License as published by
Xthe Free Software Foundation; either version 1, or (at your option)
Xany later version.
X
XNOTATION is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
XGNU General Public License for more details.
X
XYou should have received a copy of the GNU General Public License
Xalong with NOTATION; see the file COPYING.  If not, write to
Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
X
X/* --------------------- data part ---------------------- */
X
X/* les tableaux suivants sont les tables de transcription de notation
X   selon les langages
X   */
X#ifdef __STDC__
X#include <stdlib.h>
X#endif
X#include <stdio.h>
X#include <string.h>
X#include <ctype.h>
X
X#include "chesstype.h"
X#include "notation.h"
X#include "drivers.h"
X#include "lexer.h"
X
Xextern void close_files();
X
Xchar * version_string =
X  "@(#)notation.c	3.1 (C) Henry Thomas\tVersion 3.1\tDated 6/16/91";
X
Xstatic char * keywords[]= {
X  "@startplay" , "@clearboard" , "@showboard" ,
X  "@whitesmove", "@blacksmove", "@configwhite", "@configblack" ,
X  "@default" , 
X  /* these are keywords with arguments */
X  "@title", "@subtitle", "@score", "@language",
X  /* "special" keyword */
X  "@special", 
X  /* null and final keyword */
X  "@null"
X  };
X
Xint configuring = FALSE ;
Xint configside = 0 ;
X
X
Xstatic char * t_language[] = {
X  "french", "english", "italian", "spanish", "german", "dutch",
X  "czech",  "hungarian","polish", "romanian", "FIDE"
X};
X
Xstatic int in_language = DEFAULT_INPUT_LANGUAGE ;
Xstatic int out_language = DEFAULT_OUTPUT_LANGUAGE ;
X
Xstatic char c_language[NBLANGUAGES][7] = {
X/* french    */  { '@' ,'R' , 'D' , 'T' , 'F' , 'C' , 'P' },
X/* english   */  { '@' ,'K' , 'Q' , 'R' , 'B' , 'N' , 'P' },
X/* italian   */  { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' },
X/* spanish   */  { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' },
X/* german    */  { '@' ,'K' , 'D' , 'T' , 'L' , 'S' , 'B' },
X/* dutch     */  { '@' ,'K' , 'D' , 'T' , 'L' , 'P' , 'O' },
X/* czech     */  { '@' ,'K' , 'D' , 'V' , 'S' , 'J' , 'P' },
X/* hungarian */  { '@' ,'K' , 'V' , 'B' , 'F' , 'H' , 'G' },
X/* polish    */  { '@' ,'K' , 'H' , 'W' , 'G' , 'S' , 'P' },
X/* romanian  */  { '@' ,'R' , 'D' , 'T' , 'N' , 'C' , 'P' },
X/* FIDE      */  { '@' ,'K' , 'D' , 'T' , 'S' , 'N' , 'P' }
X/* UNIMPLEMENTED ... */
X/* user_def  *//*{ '@' ,'X' , 'X' , 'X' , 'X' , 'X' , 'X' }*/
X/* russian not implemented : ASCII russian is an oxymoron */
X/* russian   *//*{ '@' ,'K' , 'F' , 'D' , 'C' , 'K' , 'P' }*/
X	       };
X
X/* input translation table */
Xchar *in_table;
X 
X
Xchar *  c_roque[] = { "O-O" , "O-O-O" , "o-o" , "o-o-o" , "0-0" , "0-0-0" };
X
X/* various notations for en passant */
X#define N_EP 2
Xchar * c_en_passant[] = { "ep" , "e.p." } ;
X
X
X/* notation for catch */
Xchar c_prise ='x';
X
X/* various comments */
Xchar * c_comments[] = { "+" , "++" , 
X			  "?" , "??", "!", "!!", "!?", "?!",
X			  "mate", "draw" };
X
X/* movement tables */
X/* move only */
X/* white pawn, move */
X#define NB_M_PAWN_MOVE_WD 2
Xstatic int m_pawn_move_wd [][2] = {
X  { 1, 0}, {2, 0}
X};
X
X/* black pawn, move */
X#define NB_M_PAWN_MOVE_BD 2
Xstatic int m_pawn_move_bd [][2] = {
X  {-1, 0}, {-2, 0}
X};
X
X/* TRICK = we have added the catching move at the end of
X   the non catching ones; so in check_depl, we try first 
X   the non catching one and then the catching one.
X   So, even if catching (x) is non indicated in the input, 
X   we succeed in guessing the move
X   */
X/* white pawn, move */
X/*#define NB_M_PAWN_WD 2*/
X#define NB_M_PAWN_WD 4
Xstatic int m_pawn_wd [][2] = {
X  { 1, 0}, {2, 0},
X/* catch... */
X  { 1, 1}, { 1,-1}
X};
X
X/* white pawn, catch */
X#define NB_M_PAWN_WX 2
Xstatic int m_pawn_wx [][2] = {
X  { 1, 1}, { 1,-1}
X};
X
X/* black pawn, move */
X/*#define NB_M_PAWN_BD 2*/
X#define NB_M_PAWN_BD 4
Xstatic int m_pawn_bd [][2] = {
X  {-1, 0}, {-2, 0},
X/* catch... */
X  {-1, 1}, {-1,-1} 
X};
X
X/* black pawn, catch */
X#define NB_M_PAWN_BX 2
Xstatic int m_pawn_bx [][2] = {
X  {-1, 1}, {-1,-1} 
X};
X
X
X#define NB_M_KNIGHT  8
Xstatic int m_knight[][2] = { 
X  { 2, 1}, { 2,-1}, {-2, 1}, {-2,-1},
X  { 1, 2}, { 1,-2}, {-1, 2}, {-1,-2}
X};
X
X#define NB_M_BISHOP 28
Xstatic int m_bishop[][2] = {
X  { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
X  { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
X  {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
X  {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}
X};
X
X#define NB_M_ROOK 28
Xstatic int m_rook[][2] = {
X  { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
X  {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
X  { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
X  { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
X};
X
X#define NB_M_QUEEN 56
Xstatic int m_queen[][2] = {
X  { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
X  { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
X  {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
X  {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1},
X  { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
X  {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
X  { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
X  { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
X};
X
X#define NB_M_KING 8
Xstatic int m_king[][2] = {
X  { 1, 1}, { 1, 0}, { 1,-1},
X  {-1, 1}, {-1, 0}, {-1,-1},
X  { 0, 1}, { 0, -1}
X};
X
X
X/* I/O */
XFILE * infile ;
XFILE * fhelp;
X
Xstatic char * t_output[] = 
X{ "ascii", "postscript", "tex", "roff", "xchess", "gnu" };
X
X/* stack -- used for variation */
X
X/* stack element */
Xtypedef struct {
X  depl * d;
X  game * b;
X  
X  /* we don't stack drivers, but only to variables */
X  int d1,d2; /* iswhiteturn and interrupt */
X} stack_elt ;
X
X/* size of the stack
X   0 = ordinary play
X   1 = level 1 variation
X   2 = level 2 variation
X   3 = level 3 variation
X*/
X#define VARIATION_MAX 3
X
X/* the stack itself */
Xstatic stack_elt stack[VARIATION_MAX];
X
X/* top of the stack */
X/* --> explicit in dr->variation */
X
X
X/* ---------- automata definitions --------- */
X/* table for syntaxic analysis of move */
X
X#define FINAL	10
X#define TML 	FINAL   /* terminal state */
X#define NBETAT 	11
X#define NBCLAS 	8
X
X/* successor of state */
Xstatic int transit[NBETAT][NBCLAS] = { 
X/*   P a-h 1-8   -   x   =  \0   ? */ 
X/*(  0   1   2   3   4   5   6   7)*/
X  {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
X  { -1,  2, -1, -1,  4, -1, -1, -1 }, /* etat  1 */
X  { -1,  6,  3,  4,  4,  8,TML,TML }, /* etat  2 */
X  { -1,  6, -1,  4,  4,  8,TML,TML }, /* etat  3 */
X  {  5,  6, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
X  { -1,  6, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
X  { -1, -1,  7, -1, -1, -1, -1, -1 }, /* etat  6 */
X  { -1, -1, -1, -1, -1,  8,TML,TML }, /* etat  7 */
X  {  9, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
X  { -1, -1, -1, -1, -1, -1,TML,TML }, /* etat  9 */
X  { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 == terminal */
X};
X
X/* actions to do */
Xstatic int action[NBETAT][NBCLAS] = {
X/*   P a-h 1-8   -   x   =  \0   ? */ 
X  {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
X  { -1,  2, -1, -1, 10, -1, -1, -1 }, /* etat  1 */
X  { -1, 13,  3,  4,  5, 14,  6,  7 }, /* etat  2 */
X  { -1, 13, -1,  4,  5, 14,  6,  7 }, /* etat  3 */
X  {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
X  { -1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
X  { -1, -1,  3, -1, -1, -1, -1, -1 }, /* etat  6 */
X  { -1, -1, -1, -1, -1, 14,  8,  9 }, /* etat  7 */
X  { 15, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
X  { -1, -1, -1, -1, -1, -1, 17, 17 }, /* etat  9 */
X  { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 */
X};
X
X
X/* the complete play */
Xplay * theplay ;
X
X/* current game
X   the name "tos" means "top of stack"
X   */
Xstatic game * tos = GULL ;
X
X/* variable holding current move */
Xstatic depl * m = MULL ;
X
X/* the output driver */
Xstatic format * dr;
X
Xstatic int driver; /* driver type, ie gnu, ascii ... */
X
Xstatic int movecount;
X
X/* current move, used by the parser */
Xstatic int curpiece,  curcol,  curlig ;
Xstatic int curdigit, curmove;
X
X/* booleen d'erreur */
Xint error_flag = FALSE;
X
X/* move to display board */
Xstatic int count = 0 ;
X
Xstatic int move_to_display[NB_MOVE_TO_DISP] ;
Xstatic int nb_move_to_dsp = 0;
Xstatic int stop_at_display = FALSE;
X
X/* short and long form comment table */
Xchar * com_short[] = {
X#define CHESSSYMB(LET,LASC,SASC,TEX,PS,ENG,FRA) SASC,
X#include "chesssymb.def"
X ""
X };
X#undef CHESSSYMB
X
Xchar * com_long[] = {
X#define CHESSSYMB(LET,LASC,SASC,TEX,PS,ENG,FRA) LASC,
X#include "chesssymb.def"
X ""
X };
X#undef CHESSSYMB
X
X
X
X#define setboard(A,I,J,P,C)  { (A)->board[(I)][(J)] = (P) ; \
X				 (A)->color[(I)][(J)] = (C); }
X#define clsboard(A,I,J)   { (A)->board[(I)][(J)] = VOID ; \
X				(A)->color[(I)][(J)] = VOID ;}
X
X/* --------------------------- code part --------------------- */
X
X
X#ifdef __STDC__
Xstatic int ispiece(char c)
X#else
Xstatic int ispiece(c)
X     char c;
X#endif
X{
X  register int i;
X  
X  for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
X  /*(void) fprintf(stdout, "piece %d %c\n" , i , c);*/
X  return(i<NUMPIECES);
X}
X
X
X#ifdef __STDC__
Xstatic int piece(char c)
X#else
Xstatic int piece(c)
X     char c ;
X#endif
X{
X  register int i;
X  
X  for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
X  if ( i== NUMPIECES)
X    i = PAWN ;
X  return(i);
X}
X
X/* this function return yhe # entry of a keyword in a given table.
X   if key is not present, it returns the default value
X   */
X#ifdef __STDC__
Xstatic int find_keyword(char *tab[], int nbentry,int defaut,
X			char *key,int warning)
X#else
Xstatic int find_keyword(tab, nbentry,defaut,key,warning)
X     char * tab[]; /* the table to look in */
X     int nbentry;  /* number of entries */
X     int defaut;  /* the default value to return if search failed */
X     char *key;    /* the key to find */
X     int warning;  /* do we display a warning ? */
X#endif
X{
X  int i ;
X
X  for(i=0; (i< nbentry) ;i++)
X    if (strcmp(tab[i],key)==0)
X      return(i);
X
X  /* we failed to find the keyword */
X  if (warning)
X    (void) fprintf (stderr, "unknow keyword %s in this context\n",key);
X  return(defaut);
X}
X
X/* ---------- board management function ------------- */
X
X#ifdef __STDC__
Xvoid clear_board(game *g)
X#else
Xvoid clear_board(g)
X     game *g;
X#endif
X{
X  register int i,j;
X
X  for (i=0; i < 10; i++ )
X    for (j=0 ; j< 10 ; j++) {
X      g->board[i][j] = VOID;
X      g->color[i][j] = VOID;
X    }
X}
X
X#ifdef __STDC__
Xgame * new_board(void)
X#else
Xgame * new_board()
X#endif
X{
X  game * tmp;
X  int i; 
X
X  tmp = (game *) malloc (sizeof(game));
X  ALLOCP(tmp);
X  for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
X    ((int *) tmp)[i] = 0;
X  return(tmp);
X}
X
X#ifdef __STDC__
Xgame * copy_board(game *from, game *to)
X#else
Xgame * copy_board(from, to)
X     game * from;
X     game * to;
X#endif
X{
X  int i; 
X
X  for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
X    ((int *) to)[i] =  ((int *) from)[i] ;
X  return(to);
X}
X
X#ifdef __STDC__
Xvoid init_board(game *tgm)
X#else
Xvoid init_board(tgm)
X  game * tgm;
X#endif
X{
X  register int i,j;
X
X  clear_board(tgm);
X
X  for (i=1; i< 9 ; i=i+7) {
X    tgm->board[i][1]= tgm->board[i][8] = ROOK ;
X    tgm->board[i][2]= tgm->board[i][7] = KNIGHT ;
X    tgm->board[i][3]= tgm->board[i][6] = BISHOP ;
X    tgm->board[i][4]= QUEEN;
X    tgm->board[i][5]= KING;
X  }
X  for (i=2; i< 8 ; i=i+5) 
X    for (j=1; j <=8 ; j++)
X      tgm->board[i][j] = PAWN;
X
X  for (i=1; i <=2; i++)
X    for (j=1; j <=8 ; j++) {
X      tgm->color[i][j] = WHITE;
X      tgm->color[i+6][j] = BLACK ;
X    }
X}
X
X#ifdef __STDC__
Xdepl * new_move(void)
X#else
Xdepl * new_move()
X#endif
X{
X  depl * tmp;
X  int i; 
X  static int counter = 0;
X
X  tmp = (depl *) malloc (sizeof(depl));
X  ALLOCP(tmp);
X  for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
X    ((int *) tmp)[i] = 0;
X  tmp->uid = ++counter;
X  tmp->whiteturn = FALSE;
X  tmp->move = 0;
X  return(tmp);
X}
X
X
X#ifdef __STDC__
Xvoid init_move(depl *m)
X#else
Xvoid init_move(m)
X     depl *m;
X#endif
X{
X  m->move= 1 ;
X  m->whiteturn = TRUE ;
X}
X
X#ifdef __STDC__
Xdepl * copy_move(depl *from,depl *to)
X#else
Xdepl * copy_move(from,to)
X     depl * from;
X     depl * to ;
X#endif
X{
X  int i; 
X
X  for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
X    ((int *) to)[i] = ((int *) from)[i];
X
X  return(to);
X}
X
X/* add a new move as successor to the move m */
X#ifdef __STDC__
Xdepl * add_trailing_move(depl *mo)
X#else
Xdepl * add_trailing_move(mo)
X     depl * mo;
X#endif
X{
X  mo->next = new_move();
X
X  mo->next->prev = mo;
X  mo->next->next = (depl *) NULL;
X  mo->next->sub  = (depl *) NULL;
X
X  mo->next->whiteturn = !( m->whiteturn ) ;
X  mo->next->move = mo->move;
X  if ( mo->next->whiteturn) {
X    mo->next->move++;
X  }
X
X  return(mo->next);
X}
X
X#ifdef __STDC__
Xstatic depl * add_variation(depl *mo)
X#else
Xstatic depl * add_variation(mo)
X     depl * mo;
X#endif
X{
X  depl *ip ; /* insertion point */
X
X  ip = mo ;
X  while (ip->sub != (depl *) NULL )
X    ip = ip->sub ;
X  
X  ip->sub = new_move();
X
X  ip->sub->prev = mo;
X  ip->sub->next = (depl *) NULL;
X  ip->sub->sub  = (depl *) NULL;
X  
X  /* as we have a fictif element heading our list, 
X     ( generated by add_trailing_move() )
X     we have to go back in the numbering */
X  ip->sub->whiteturn =  mo->prev->whiteturn  ;
X  ip->sub->move = mo->prev->move ;
X
X  return(ip->sub);
X}
X
X
X#ifdef __STDC__
Xstatic void free_move_list(depl *d)
X#else
Xstatic void free_move_list(d)
X     depl * d;
X#endif
X{  
X
X  if (d->next != (depl *) NULL) {
X    free_move_list(d->next);
X    free(d->next);
X    d->next = (depl *) NULL;
X  }
X  if (d->sub != (depl *) NULL) {
X    free_move_list(d->sub);
X    free(d->sub);
X    d->sub = (depl *) NULL;
X  }
X}
X  
X/* this procedure undo the effect of move m on the board g */
X#ifdef __STDC__
Xstatic void undo_move(game *g,depl *m)
X#else
Xstatic void undo_move(g,m)
X     game *g;
X     depl *m;
X#endif
X{
X  int lig;
X  if (m->whiteturn)
X    lig = 1;
X  else 
X    lig = 8;
X  switch (m->type) {
X  case MOVE:
X    clsboard(g,m->tolig,m->tocol) ;
X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
X    break;
X  case PRISE:
X    setboard(g,m->tolig,m->tocol,m->prise,OPPCOLOR(m)) ;
X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
X    break;
X  case GRANDROQUE:
X    clsboard(g,lig,3) ;
X    clsboard(g,lig,3) ;
X    setboard(g,m->fromlig,5,KING,CURCOLOR(m)) ;
X    setboard(g,m->fromlig,5,ROOK,CURCOLOR(m)) ;
X    break;
X  case PETITROQUE:
X    clsboard(g,lig,6) ;
X    clsboard(g,lig,7) ;
X    setboard(g,m->fromlig,5,KING,CURCOLOR(m)) ;
X    setboard(g,m->fromlig,8,ROOK,CURCOLOR(m)) ;
X    break;
X  case EN_PASSANT:
X    clsboard(g,m->tolig,m->tocol) ;
X    setboard(g,m->tolig,m->fromcol,PAWN,OPPCOLOR(m)) ;
X
X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
X    break;
X  case PROMOTION:
X    clsboard(g,m->tolig,m->tocol);
X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
X    break;
X  case PROM_ET_PRISE:
X    setboard(g,m->tolig,m->tocol,m->prise,OPPCOLOR(m)) ;
X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
X    break;
X  default:
X    fprintf(stderr,"unable to undo move: unknown move type\n");
X    break;
X  }
X}
X
X/* variation procedures == stack manipulation */
X
X#ifdef __STDC__
Xvoid enter_variation(void)
X#else
Xvoid enter_variation()
X#endif
X{
X  int l;
X
X  l = dr->variation ;
X  
X  if (l >= VARIATION_MAX) {
X    error((stderr,"Maximum imbricated variation is %d",VARIATION_MAX));
X  } else {
X    /* save current line/variation */
X    stack[l].d = m;
X    stack[l].b = tos;
X    stack[l].d1 = dr->iswhiteturn;
X    stack[l].d2 = dr->interrupt = TRUE ;    
X    /* create new */
X    tos = new_board();
X    (void) copy_board(stack[l].b, tos);
X
X    /* A variation FOLLOWS the main line 
X       so we need to backtrack one move
X       */
X    m = add_variation(stack[l].d);
X    undo_move(tos,stack[l].d);
X
X    /* set variables */
X    l++;
X    dr->variation = l;
X
X    output_variation(dr,VARIATION_IN);
X  }
X}
X
X#ifdef __STDC__
Xvoid exit_variation(void)
X#else
Xvoid exit_variation()
X#endif
X{
X  int l ;
X
X  l = dr->variation ;
X  
X  if (l == 0) {
X    error((stderr,"You cannot exit from the main line (variation error?)"));
X  } else {
X    output_variation(dr,VARIATION_OUT);
X
X    l--;
X    free(tos);
X    free(m);
X    m = stack[l].d ;
X    tos = stack[l].b ;
X
X    dr->iswhiteturn = stack[l].d1 ;
X    dr->interrupt = stack[l].d2 ;
X    dr->variation = l;
X  }
X}
X
X/* ----------- semantic evaluation of move ----------- */
X/* check if  position lies within the board
X   */
X#ifdef __STDC__
Xint in_board(int l,int c)
X#else
Xint in_board(l,c)
X     int l,c;
X#endif
X{
X  return ((c >= 1) && (c <= 8) && (l >= 1) && (l <= 8));
X}
X
X/* check that the path from pos1 to pos2 is free
X   */
X#ifdef __STDC__
Xint path_free(int l1,int c1,int l2,int c2)
X#else
Xint path_free(l1, c1, l2, c2)
Xint l1,c1, l2, c2;
X#endif
X{
X  int li = 1 ;
X  int ci = 1 ;
X  int lig, col;
X
X
X  li = SIGN(l2-l1);
X  ci = SIGN(c2-c1);
X
X
X  if ( c1 == c2 ) {    
X    col = c1;
X    for (lig = l1 +li; lig != l2 ; lig +=li)
X      if (tos->board[lig][col] != VOID)
X	return (FALSE);
X    return(TRUE);
X  }
X
X  if ( l1 == l2) {
X    lig = l1 ;
X    for (col = c1 + ci; col != c2 ; col +=ci)
X      if (tos->board[lig][col] != VOID)
X	return (FALSE);
X    return(TRUE);
X  }
X
X  for (lig = l1+li,col =c1+ci; (lig!=l2) && (col!=c2); lig+=li, col+= ci)
X    if (tos->board[lig][col] != VOID) {
X      return (FALSE);
X    }
X  return(TRUE);
X}
X
X/* check roque is possible */
X#ifdef __STDC__
Xint check_roque(void)
X#else
Xint check_roque()
X#endif
X{
X  int lig, col ;
X
X  if (m->whiteturn)
X    lig = 1 ;
X  else
X    lig =8;
X  if (m->type == GRANDROQUE)
X    for (col = 2; col < 5 ; col++)
X      if (tos->board[lig][col] != VOID)
X	return(FALSE);
X  if (m->type == PETITROQUE)
X    for (col = 6; col < 7 ; col++)
X      if (tos->board[lig][col] != VOID)
X	return(FALSE);
X  return(TRUE);
X}
X  
X/* check -- or guess -- where a given piece come */
X#ifdef __STDC__
Xint guess_piece(void) 
X#else
Xint guess_piece() 
X#endif
X{
X  return(tos->board[m->fromlig][m->fromcol]); 
X}
X
X/* try to guess the move -- low-level function */
X#ifdef __STDC__
Xint guess_depl(int nb, int tab[][2],
X	       int * pl1, int * pc1, int l2, int c2, int path)
X#else
Xint guess_depl(nb, tab, pl1, pc1, l2,c2,path)
X     int nb;
X     int tab[][2];
X     int *pl1, *pc1;
X     int l2,c2;
X     int path;
X#endif
X{
X  int i;
X  int c,l;
X
X  for (i=0; i< nb; i++ ) {
X    l = l2 - tab[i][0];
X    c = c2 - tab[i][1];
X    if (in_board(l,c))
X      if ((tos->board[l][c] == m->piece) &&
X	  (tos->color[l][c] == CURCOLOR(m)) &&
X	  ( !path || (path && path_free(l,c, l2, c2))) &&
X	  ( ((*pl1) == 0) || ((*pl1) == l) ) &&
X	  ( ((*pc1) == 0) || ((*pc1) == c) ) )
X	  {
X	*pl1 = l;
X	*pc1 = c;
X	return(TRUE);
X      }
X  }
X  return(FALSE);
X}
X
X/* check for ambiguitey in a move
X   used in ouptut function: the piece had beenm already moved and
X   if we guess another move, there is an ambiguity
X   */
X#ifdef __STDC__
Xint ambiguity(int frompiece, int l2, int c2)
X#else
Xint ambiguity(frompiece, l2, c2)
X     int frompiece, l2, c2 ;
X#endif
X{
X  int l1 = 0 ;
X  int c1 = 0 ;
X
X  switch(frompiece) {
X  case PAWN:
X    if (m->type == PRISE) {
X      if (m->whiteturn)
X	return(guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE));
X      else
X	return(guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE));
X   } else {
X      if (m->whiteturn)
X	return(guess_depl(NB_M_PAWN_MOVE_WD, m_pawn_move_wd, 
X			  &l1,&c1, l2,c2, FALSE));
X      else
X	return(guess_depl(NB_M_PAWN_MOVE_BD, m_pawn_move_bd, 
X			  &l1,&c1, l2,c2, FALSE));
X    }
X	/* break; */
X  case KNIGHT:
X    return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
X	/* break; */
X  case BISHOP:
X    return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
X	/* break; */
X  case ROOK:
X    return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
X	/* break; */
X  case QUEEN:
X    return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
X	/* break; */
X  case KING:
X    return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
X	/* break; */
X  default:
X    break;
X  }
X  return(TRUE);
X}
X
X#ifdef __STDC__
Xint check_move(depl *m)
X#else
Xint check_move(m)
X     depl * m;
X#endif
X{
X  int l1,c1,l2,c2;
X  int tmp; /* tmp boolean */
X 
X  l1 = m->fromlig;
X  c1 = m->fromcol;
X  l2 = m->tolig;
X  c2 = m->tocol;
X
X  if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
X    return(check_roque());
X
X  if ((tos->board[l1][c1] != m->piece)||
X      (tos->color[l1][c1] != CURCOLOR(m))){
X    fprintf(stderr,"hum... piece should be %d \n",tos->board[l1][c1]);
X    error ((stderr,": from position and piece not coherent at move (%d,%d)\n",
X	    m->move,m->whiteturn));
X    return(FALSE);
X  }
X
X  /* if prise === FALSE, we must not take a piece */
X  if (tos->board[l2][c2] != VOID 
X      && (m->type != PRISE) && (m->type != PROM_ET_PRISE)) {
X    (void) fprintf(stderr,"catching not indicated at move %d\n",m->move);
X    return(FALSE);
X  }
X
X  /* prendre une de ses propres pieces */
X  if (tos->color[l2][c2] == tos->color[l1][c1] && m->prise) {
X    (void) fprintf(stderr,"attempt to catch same color piece at move %d\n",
X		   m->move);
X    return(FALSE);
X  }
X
X  /* we check if the move is a possible one for the piece
X     */
X
X  switch(m->piece) {
X  case PAWN:
X    if (m->prise) {
X      if (m->whiteturn)
X	tmp = guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
X      else
X	tmp = guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
X   } else {
X      if (m->whiteturn)
X	tmp = guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE);
X      else
X	tmp = guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE);
X    }
X    /* is it a "prise en passant " */
X    if ((c1 != c2) && (tos->board[l2][c2] == VOID)
X	&& (tos->board[l1][c2] == PAWN)) {
X      m->type = EN_PASSANT ;
X      /* we must perform here the "en passant" test */
X      tos->board[l1][c2] = VOID ;
X      tos->color[l1][c2] = VOID ;
X      tmp = TRUE;
X    }
X    return(tmp);
X    /* break; */
X  case KNIGHT:
X    return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
X    /* break; */
X  case BISHOP:
X    return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
X    /* break; */
X  case ROOK:
X    return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
X    /* break; */
X  case QUEEN:
X    return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
X    /* break; */
X  case KING:
X    return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
X    /* break; */
X  default:
X    break;
X  }
X
X  return(TRUE);
X}
X
X/* try to guess the move -- used for shortened notation
X   */
X#ifdef __STDC__
Xint guess_move(void)
X#else
Xint guess_move()
X#endif
X{
X  int l1,c1,l2,c2;
X
X  if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
X    return(TRUE);
X
X  l1 = m->fromlig ;
X  c1 = m->fromcol ;
X  l2 = m->tolig;
X  c2 = m->tocol;
X
X  switch(m->piece) {
X  case PAWN:
X    if (m->prise) {
X      if (m->whiteturn)
X	(void) guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
X      else
X	(void) guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
X    } else {
X      if (m->whiteturn)
X	(void) guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE); 
X      else
X	(void) guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE); 
X    }
X    break;
X  case KNIGHT:
X    (void) guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE);
X    break;
X  case BISHOP:
X    (void) guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE);
X    break;
X  case ROOK:
X    (void) guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE);
X    break;
X  case QUEEN:
X    (void) guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE);
X    break;
X  case KING:
X    (void) guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE);
X    break;
X  default:
X    break;
X  }
X
X  if ((l1 == 0) || (c1 == 0)) {
X    if (m->whiteturn)
X      error((stderr,"unable to guess move %d white, with piece %d\n",
X	     m->move,m->piece));
X    else
X      error((stderr,"unable to guess move %d black, with piece %d\n",
X	     m->move,m->piece));
X    return(FALSE);
X  } else {
X    m->fromcol = c1;
X    m->fromlig = l1;
X    return(TRUE);
X  }
X}
X
X/* --------------- execution of move ----------------- */
X
X/* clear a position */
X#ifdef __STDC__
Xint clear_pos(int lig, int col)
X#else
Xint clear_pos(lig,col)
X     int lig;
X     int col;
X#endif
X{
X  tos->board[lig][col] = VOID ;
X  tos->color[lig][col] = VOID ;
X  return(TRUE);
X}
X
X/* configure the board */
X#ifdef __STDC__
Xint configure(void)
X#else
Xint configure()
X#endif
X{
X  if (configuring) {
X    if (m->piece == VOID)
X      m->piece = PAWN ;
X    tos->board[m->tolig][m->tocol] = m->piece ;
X    tos->color[m->tolig][m->tocol] = configside ;
X  }
X  return(TRUE);
X}
X
X/* execute a move, no checking */
X#ifdef __STDC__
Xint execute_move(void)
X#else
Xint execute_move()
X#endif
X{
X  register int i;
X
X  if (m->piece == VOID )
X    m->piece = PAWN;
X
X  if ((m->fromlig == 0) || (m->fromcol == 0))
X    (void) guess_move();
X  
X  /* supply to the -- maybe -- deficiency of input notation
X     */
X  if ((m->fromlig !=0) || (m->fromcol != 0))
X    m->piece = tos->board[m->fromlig][m->fromcol];
X
X  if (tos->board[m->tolig][m->tocol] != VOID) {
X    m->type = PRISE;
X    m->prise = tos->board[m->tolig][m->tocol] ;
X  }
X
X  if (!check_move(m)) {
X    if (m->whiteturn)
X      error((stderr,"white move %d illegal\n",m->move));
X    else
X      error((stderr,"black move %d illegal\n",m->move));
X  }
X
X  if (m->type == PETITROQUE) {
X    if (m->whiteturn)
X      curlig = 1 ;
X    else
X      curlig = 8 ;
X    tos->board[curlig][7] = KING;
X    tos->board[curlig][6] = ROOK;
X    tos->color[curlig][7] = tos->color[curlig][5] ;
X    tos->color[curlig][6] = tos->color[curlig][5] ;
X    (void) clear_pos(curlig, 5);
X    (void) clear_pos(curlig, 8);
X  }
X  if (m->type == GRANDROQUE) {
X    if (m->whiteturn)
X      curlig = 1 ;
X    else
X      curlig = 8 ;
X    tos->board[curlig][3] = KING;
X    tos->board[curlig][4] = ROOK;
X    tos->color[curlig][3] = tos->color[curlig][5] ;
X    tos->color[curlig][4] = tos->color[curlig][5] ;
X    (void) clear_pos(curlig, 5);
X    (void) clear_pos(curlig, 1);
X  }
X
X        
X  if (!(m->type == GRANDROQUE) || (m->type == PETITROQUE)) {
X    if (m->piece == VOID)
X      m->piece = tos->board[m->fromlig][m->fromcol];
X    /*if (m->topiece == VOID)
X      m->topiece = tos->board[m->fromlig][m->fromcol];*/
X    tos->board[m->tolig][m->tocol] = tos->board[m->fromlig][m->fromcol];
X    tos->color[m->tolig][m->tocol] = tos->color[m->fromlig][m->fromcol];
X    (void) clear_pos(m->fromlig,m->fromcol);
X  }
X  
X  if ((m->type == PROMOTION) || (m->type == PROM_ET_PRISE))
X    tos->board[m->tolig][m->tocol] = m->promotion ;
X     
X  output_move(dr,m);
X
X  if (error_flag) {
X    (void) fprintf(dr->outfile, "\nlast position encountered:\n");
X    output_board(dr,tos);
X    close_files();
X    exit(0);
X  }
X
X  /* do we need to display the move ? */
X  if (nb_move_to_dsp > 0) {
X    for (i=0; i < nb_move_to_dsp; i++)
X      if (m->move == (move_to_display[i] ) && !m->whiteturn ) {
X	output_board(dr,tos);
X	if (stop_at_display) {
X	  output_end(dr);
X	  close_files();
X	  exit(0);
X	}
X      }
X  }
X
X  return(TRUE);
X}
X
X/* ------------------ automata ----------------------- */
X
X/* categorise the input for the automata */
X#ifdef __STDC__
Xint typechar(char c)
X#else
Xint typechar(c)
X     char c;
X#endif
X{
X  if (ispiece(c))
X    return(0);
X  if ((c >=  'a') && ( c <= 'h'))
X    return(1);
X  if ((c >=  '1') && ( c <= '8'))
X    return(2);
X  if ( c== '-' )
X    return(3);
X  if ((c == 'x') || (c == 'X' ))
X    return(4);
X  if (c == '=' )
X    return(5);
X  if (c == '\0' )
X    return(6);
X  return(7);
X}
X
X
X/* execute the actions decided by the automata */
X#ifdef __STDC__
Xint execute(int num,char c)
X#else
Xint execute(num,c)
X     int num;
X     char c;
X#endif
X{
X  switch (num) {
X  case 1: /* set cur piece */
X    curpiece = piece(c);
X    break;
X  case 2: /* set cur col */
X    curcol = lettertocol(c);
X    break;
X  case 3: /* set cur lig */
X    curlig = lettertolig(c);
X    break;
X  case 4: /* from = cur ; prise = false */
X    m->piece = curpiece ;
X    m->fromcol = curcol ;
X    m->fromlig = curlig;
X    /*m->topiece = curpiece;*/
X    break;
X  case 5: /* from = cur ; prise = true */
X    m->piece = curpiece ;
X    m->fromcol = curcol ;
X    m->fromlig = curlig;
X    m->type = PRISE ;
X    m->prise = curpiece;
X    break;
X  case 6: /* to = cur ; guess from */
X  case 7: /* to = cur ; guess from ; parse remaining token */
X    m->piece = curpiece ;
X    m->tocol = curcol;
X    m->tolig = curlig ;
X
X    /*m->topiece = curpiece ; /* ? */
X
X    if (configuring)
X      (void) configure();
X    else {
X      (void) execute_move();
X    }
X    break;
X  case 8: /* to = cur */
X  case 9: /* to = cur */
X    m->tocol = curcol;
X    m->tolig = curlig ;
X
X    if (configuring)
X      (void) configure();
X    else {
X      (void) execute_move();
X    }
X    break;
X  case 10: /* piece = cur piece ; prise = true */
X    /* later : guess from position */
X    m->piece = curpiece ;
X    m->type = PRISE ;
X    break;
X  case 11: /* grand roque */
X  case 12: /* petit roque */
X    (void) execute_move();
X    break;
X  case 13: /* case of simpliest algebraic notation ;
X	      only e2e4 : this is the transition from e2 to e4
X	      also the case of move such as Nge2
X	      from =cur; prise = FALSE;
X	      also:
X	      curcol = ...
X	      */
X    m->piece = curpiece ;
X    m->fromcol = curcol ;
X    m->fromlig = curlig;
X
X    m->type = MOVE;
X    curcol = lettertocol(c);
X  case 14: /* promotion, the "=" */
X    break;
X  case 15: /* promotion, the piece name */
X    /* to = cur ; guess from */
X  case 16: 
X    /* to = cur */
X
X    m->tocol = curcol;
X    m->tolig = curlig ;
X    /*m->topiece = curpiece ;*/
X
X    if (m->type == PRISE )
X      m->type = PROM_ET_PRISE ;
X    else
X      m->type = PROMOTION ;
X    m->promotion = curpiece = piece(c) ;
X
X    break;
X  case 17: /* execute move for promotion */
X    (void) execute_move();
X    break;
X  case -1:
X    break;
X  default:
X    break;
X  }
X  return(TRUE);
X}
X
X#ifdef __STDC__
Xint parse_number(char *token)
X#else
Xint parse_number(token)
X     char *token;
X#endif
X{
X  int curmove = 0 ;
X  int i;
X
X  /* check coherency with internal numbering */
X  i = 0;
X  while (isdigit(token[i])) {
X   curmove = curmove * 10 +  ((int) token[i++] - (int) '0' );
X  }
X  movecount = curmove ;
X  return(TRUE);
X}
X
X#ifdef __STDC__
Xint parse_text(char *text)
X#else
Xint parse_text(text)
X     char *text;
X#endif
X{
X  output_text(dr,T_TEXT, text, 0);
X  return(TRUE);
X}
X
X#ifdef __STDC__
Xint parse_comment(char *com)
X#else
Xint parse_comment(com)
X     char *com;
X#endif
X{
X  int t;
X
X  if (com[0] == '$')
X    /* we look in the long ascii table */
X    t = find_keyword(com_long, NUM_COM_CODE, NUM_COM_CODE, com, TRUE);
X  else {
X    /* we look for the comment in the short ascii table */
X    t = find_keyword(com_short, NUM_COM_CODE, NUM_COM_CODE, com,FALSE);
X    if (t == NUM_COM_CODE)
X      fprintf (stderr,"\nWhat is \"%s\" ?\n",com);   
X  }
X  if (t != NUM_COM_CODE)
X    output_text(dr,T_COMMENT, com, t);
X  return(TRUE);
X}
X
X#ifdef __STDC__
Xint parse_keyword(char *token, char *text)
X#else
Xint parse_keyword(token,text)
X     char *token;
X     char *text;
X#endif
X{
X  char c;
X
X  switch (find_keyword(keywords, NBKEYWORD, KNULL, token, TRUE)) {
X  case START:
X    /* don't forget we are configuring the previous move */
X    /* -> move 0, black */
X    configuring = FALSE;
X    m->move = 0;
X    m->whiteturn = FALSE;
X    break;
X  case CLEAR:
X    clear_board(tos);
X    m= theplay->chain;
X    free_move_list(m);
X    break;
X  case SHOWBOARD:
X    output_board(dr,tos);
X    break;
X  case TOWHITE:
X    /* don't forget we are configuring the previous move */
X    /* reset to 0,black --> 1,white */
X    m->move = 0;
X    m->whiteturn = FALSE;
X    break;
X  case TOBLACK:
X    /* reset to 1,white -> 1 black */
X    m->move = 1;
X    m->whiteturn = TRUE;
X    break;
X  case CONFIGWH:
X    configuring = TRUE ;
X    configside = WHITE;
X    m= theplay->chain;
X    free_move_list(m);
X    break;
X  case CONFIGBL:
X    configuring = TRUE ;
X    configside = BLACK;
X    m= theplay->chain;
X    free_move_list(m);
X    break;
X  case DEFAULTP:
X    init_board(tos);
X    m= theplay->chain;
X    free_move_list(m);
X    break;
X  case TITLE:
X    output_text(dr, T_TITLE, text, NULL);
X    break;
X  case SUBTITLE:
X    output_text(dr, T_SUBTITLE, text, NULL);
X    break;
X  case SCORE:
X    output_text(dr, T_SCORE, text, NULL);
X    break;
X  case LANGUE:
X    in_language = find_keyword (t_language, NBLANGUAGES, in_language,
X			       text,TRUE);
X    associe_traduction( &in_table, in_language);	       
X    break;
X  case SPECIAL: /* all input, up to \n is copied to output */
X    while ((( c = getc(infile)) != EOF) && (c != '\n'))
X      (void) putc (c,dr->outfile);
X    putc ('\n', dr->outfile);
X    break;
X  case KNULL:
X  default:
X    fprintf(stderr,"unknown keyword %s\n",token);
X    break;
X  }
X  return(TRUE);
X}
X
X#ifdef __STDC__
Xint parse_roque(char *token)
X#else
Xint parse_roque(token)
X     char * token;
X#endif
X{ 
X  int i;
X
X  for (i=0; i < NBROQUE && (strcmp(c_roque[i],token)!=0); i++) ;
X  if ( i < NBROQUE ) {
X    
X    m = add_trailing_move(m);
X    init_parse(m);
X
X    if (strlen(token) == 3) {
X      m->type = PETITROQUE ;
X      (void) execute(12,DUMMYCHAR);
X    } else {
X      m->type = GRANDROQUE ;
X      (void) execute(11,DUMMYCHAR);
X    }
X    /*(void) fprintf(stderr,"ROQUE\n");*/
X    return(TRUE);
X  }
X
X  return(FALSE);
X}
X
X#ifdef __STDC__
Xint  parse_move(char *token)
X#else
Xint  parse_move(token)
X     char *token;
X#endif
X{
X  register int i;
X  int correcte = FALSE ;
X  int erreursyntaxe = FALSE ;
X  int etat =0;
X  int code;
X  
X  m = add_trailing_move(m);
X  init_parse(m);
X  m->type = MOVE;
X
X  i=0;
X  while ( !correcte && !erreursyntaxe ) {
X    code = typechar(token[i]);
X    (void) execute(action[etat][code],token[i]);
X    etat = transit[etat][code] ;
X    if (etat == -1) 
X      erreursyntaxe = TRUE;
X    if (etat == FINAL)
X      correcte = TRUE ;
X    i++;
X  }
X  if (erreursyntaxe) {
X    (void) fprintf(stderr, "no comprende, senor: %s\n",token);
X    return(FALSE);
X  }
X  if (correcte) {
X    /*(void) fprintf(stderr, "ia panimaiou, davai\n");*/
X  }
X  /*init_parse(m);*/
X  return(TRUE);
X}
X
X#ifdef __STDC__
Xvoid init_parse(depl *m)
X#else
Xvoid init_parse(m)
X     depl * m ;
X#endif
X{
X
X  /* global position and piece variable initialised to 0
X     */
X  /* move and whiteturn unchanged */ 
X
X  m->type = MOVE ;
X
X  curpiece = m->piece = VOID ;
X  curcol = m->tocol = m->fromcol = 0;
X  curlig = m->tolig = m->fromlig = 0;
X
X  m->promotion = VOID;
X  m->prise = VOID;
X  m->is_check = FALSE ;
X
X  curdigit = curmove = 0;
X
X  /*if (movecount != m->move)
X    (void) fprintf(stderr,"problem in move numbering: %d vs %d\n",
X		   m->move, movecount);*/
X
X}
X
X/* ------------------- top routines -------------------- */
X
X/* cette fonction analyse les arguments de la ligne de commande
X   */
X#ifdef __STDC__
Xint parse_options(int argc,char *argv[])
X#else
Xint parse_options(argc,argv)
X     int argc;
X     char * argv[];
X#endif
X{
X  int narg =1 ;
X  int i;
X  register int c;
X  char cp[132];
X  char chaine[MAXTOKLEN];
X
X  infile = stdin;
X  dr->outfile = stdout;
X  nb_move_to_dsp = 0;
X
X  while (narg < argc ) {
X    (void) strcpy (cp,argv[narg]);
X    switch (cp[0]) {
X    case '-' :
X      switch (cp[1]) {
X      case 'f' : /* from langage */
X	if  ((narg+1) >= argc )
X	  fatal((stderr,"missing argument to %s option",cp));
X	narg++ ;
X	in_language = find_keyword (t_language, NBLANGUAGES,
X				    DEFAULT_INPUT_LANGUAGE,
X				    argv[narg],TRUE);
X	break;
X      case 't' : /* to langage */
X	if  ((narg+1) >= argc )
X	  fatal((stderr,"missing argument to %s option",cp));
X	narg++ ;
X	out_language = find_keyword (t_language, NBLANGUAGES,
X				     DEFAULT_OUTPUT_LANGUAGE,
X				     argv[narg],TRUE);
X	break;
X      case 'o' : /* next arg is output file */
X	narg++ ;
X	if ((dr->outfile = fopen (argv[narg],"w+")) == NULL) {
X	  (void) fprintf (stderr,"can't open %s output file\n",argv[narg]);
X	  (void) fprintf (stderr,"assume stdout for output\n");
X	}
X	break;
X      case 'e':
X	if  ((narg+1) >= argc )
X	  fatal((stderr,"missing argument to %s option",cp));
X	narg++ ;
X
X	i=0;
X	nb_move_to_dsp = 0;
X	move_to_display[nb_move_to_dsp] = 0;
X	while (isdigit(argv[narg][i])) {
X	  move_to_display[nb_move_to_dsp] =
X	    ((int) argv[narg][i] - (int) '0')
X	      + move_to_display[nb_move_to_dsp] * 10;
X	  i++;
X	}
X	nb_move_to_dsp++;
X	stop_at_display = TRUE;
X	break;
X      case 'c':
X	if  ((narg+1) >= argc )
X	  fatal((stderr,"missing argument to %s option",cp));
X	narg++ ;
X
X	i=0;
X	while (isdigit(argv[narg][i])) {
X	  move_to_display[nb_move_to_dsp] = 0;
X	  while (isdigit(argv[narg][i])) {
X	    move_to_display[nb_move_to_dsp] =
X	      ((int) argv[narg][i] - (int) '0')
X	      + move_to_display[nb_move_to_dsp] * 10;
X	    i++;
X	  }
X	  nb_move_to_dsp++;
X
X	  if (nb_move_to_dsp > NB_MOVE_TO_DISP)
X	    fatal((stderr,"max. number of move to display exceeded"));
X
X	  /* process next number */
X	  if (argv[narg][i] == ',')
X	    i++;
X	}
X	break;
X      case 'a': /* algebraic output */
X	dr->output_move_format = ALGEBRAIC;
X	break;
X      case 's':  /* shortened output */
X	dr->output_move_format = SHORTENED;
X	break;
X      case 'b': /* display only the board, no move */
X	dr->only_board = TRUE;
X	break;
X      case 'd': /* output driver */
X	if  ((narg+1) >= argc )
X	  fatal((stderr,"missing argument to %s option",cp));
X	narg++ ;
X	driver = find_keyword(t_output, NB_DRIVER, DEFAULT_DRIVER,
X			      argv[narg],TRUE);
X	break;
X      case 'i': /* no headers */
X	dr->print_headers = FALSE;
X	break;
X      case 'v': /* print version */
X	/* this already done, so exit() */
X	exit(0);
X	break;
X      case 'h': /* help file */
X	(void) strcpy(chaine,LIB_DIR);
X        if ((fhelp = fopen(strcat(chaine,HELP_FILE),"r")) == NULL)
X          fatal((stderr,"Can't find help file.\n"));
X        else {
X          while ((c = getc(fhelp)) != EOF)
X            (void) fputc(c,stderr);
X          (void) fclose(fhelp);
X	  exit(0);
X        }
X         break;
X      default:
X	error((stderr,"unknown command line options %s\n",cp));
X	break;
X      }
X      break;
X    default: /* assume this is the input file */
X      if ((infile = fopen (cp,"r")) == NULL)
X	fatal((stderr,"can't open %s input file\n",cp));
X    }
X    narg++;
X  } /* process next arg */
X  return(argc);
X}
X
X#ifdef __STDC__
Xvoid close_files(void)
X#else
Xvoid close_files()
X#endif
X{
X  if (!((infile == stdin)||(infile == NULL)))
X    (void) fclose(infile);
X  if (dr->outfile != stdout )
X    (void) fclose(dr->outfile);
X}
X
X#ifdef __STDC__
Xint associe_traduction (char **table, int language)
X#else
Xint associe_traduction (table, language)
Xchar ** table;
Xint language ;
X#endif
X{
X  if (language < 0 || (language >= NBLANGUAGES))
X    error((stderr,"unknown language\n"));
X  else
X    *table = c_language[language];
X  return(language);
X}
X
X#ifdef __STDC__
Xstatic void print_all_play(play *p)
X#else
Xstatic void print_all_play(p)
Xplay *p;
X#endif
X{ 
X  depl *d;
X  d = p->chain;
X  while (d->next != NULL){
X    d = d->next;
X    output_move(dr,d);
X  }
X}
X
X/* ------------- main --------------------- */
X
X#ifdef __STDC__
Xvoid main(int argc,char *argv[])
X#else
Xint main(argc,argv)
X     int argc;
X     char * argv[];
X#endif
X{
X  (void) fprintf(stderr,"%s\n",version_string);
X  
X  /* allocation of driver descriptor */
X  dr = new_driver();
X
X  /* default configuration */
X  init_driver(dr,DEFAULT_DRIVER);
X  (void) associe_traduction(&in_table,  DEFAULT_INPUT_LANGUAGE );
X  (void) associe_traduction(&(dr->out_table), DEFAULT_OUTPUT_LANGUAGE);
X
X  (void) parse_options(argc,argv);
X
X  (void) associe_traduction (&in_table, in_language);
X  (void) associe_traduction (&(dr->out_table), out_language);
X
X  /* assoc driver */
X  init_driver(dr,driver);
X
X  configuring = FALSE;
X  configside = VOID;
X
X  /* initialise output file */
X  output_init(dr);
X
X  if (error_flag)
X    fatal((stderr,"too many errors"));
X
X  /* allocation of board descriptor */
X  tos = new_board();
X  init_board(tos);
X
X  /* allocation of move descriptor */
X  m = new_move();
X  m->type = VOID ;
X  /*init_move(m);*/
X  
X  /* allocation of the play descriptor */
X  theplay = (play *) malloc (sizeof(play)) ;
X  theplay->initial = tos ;
X  theplay->chain   = m ;
X  movecount = 1;
X
X  /* main analysis routine */
X  yyin = infile ;
X  yyout = stderr ;
X
X  /*init_parse(m); */
X  yylex();
X
X  if ((count == 0) && !error_flag)
X    output_board(dr,tos);
X
X  if (error_flag) {
X    error((stderr,"last valid position:\n"));
X    output_board(dr,tos);
X    fatal((stderr,"too many errors"));
X  }
X      
X  /* terminates output files */
X  output_end(dr);
X
X  /* close files */
X  close_files();
X
X  /* exit properly */
X#ifdef __STDC__
X#else
X  exit(0);
X#endif
X}
END_OF_FILE
if test 40751 -ne `wc -c <'notation.c'`; then
    echo shar: \"'notation.c'\" unpacked with wrong size!
fi
# end of 'notation.c'
fi
echo shar: End of archive 4 \(of 4\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

--
Henry Thomas - IRISA 		 - E-mail: Henry.Thomas at irisa.fr 
Campus Universitaire de Beaulieu - Phone: (+33)99 36 20 00 +549  
35042 RENNES CEDEX FRANCE 	 - Fax: (+33)99 38 38 32 Telex: UNIRISA 950473F
Telex Atlas X400: /X121=842950473/@atlas.fr, Fax:/X121=200099383832/@atlas.fr
--

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.



More information about the Comp.sources.misc mailing list