home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume18 / notation / part03 / notation.c
C/C++ Source or Header  |  1991-04-13  |  31KB  |  1,315 lines

  1. /* Programme d'analyse de notation echiquienne
  2.    Copyright (C) 1990 Henry Thomas
  3.    Nom: notation.c
  4.    Auteur: Henry Thomas
  5.    Date: 27/11/90
  6.    */
  7. /* @(#)notation.c    2.1 4/11/91 (C) Henry Thomas */
  8. /*
  9. This file is part of NOTATION program.
  10.  
  11. NOTATION is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; either version 1, or (at your option)
  14. any later version.
  15.  
  16. NOTATION is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with NOTATION; see the file COPYING.  If not, write to
  23. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  24.  
  25. /* --------------------- data part ---------------------- */
  26.  
  27. /* les tableaux suivants sont les tables de transcription de notation
  28.    selon les langages
  29.    */
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <ctype.h>
  33.  
  34. #include "chesstype.h"
  35. #include "drivers.h"
  36. #include "notation.h"
  37. #include "lexer.h"
  38.  
  39. extern void close_files();
  40.  
  41.  
  42. char * version_string =
  43.   "@(#)notation.c    2.1 (C) Henry Thomas\tVersion 2.1\tDated 4/11/91";
  44.  
  45. static char * keywords[]= {
  46.   "@startplay" , "@clearboard" , "@showboard" ,
  47.   "@whitesmove", "@blacksmove", "@configwhite", "@configblack" ,
  48.   "@default" , "@special", "@null"
  49.   };
  50.  
  51. int configuring = FALSE ;
  52. int configside = 0 ;
  53.  
  54.  
  55. static char * t_language[] = {
  56.   "french", "english", "italian", "spanish", "german", "dutch" };
  57.  
  58. static int in_language = DEFAULT_INPUT_LANGUAGE ;
  59. static int out_language = DEFAULT_OUTPUT_LANGUAGE ;
  60.  
  61. static char c_french[]  = { '@' ,'R' , 'D' , 'T' , 'F' , 'C' , 'P' } ;
  62. static char c_english[] = { '@' ,'K' , 'Q' , 'R' , 'B' , 'N' , 'P' } ;
  63. static char c_italian[] = { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' } ;
  64. static char c_spanish[] = { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' } ;
  65. static char c_german[]  = { '@' ,'K' , 'D' , 'T' , 'L' , 'S' , 'B' } ;
  66. static char c_dutch[]   = { '@' ,'K' , 'D' , 'T' , 'L' , 'P' , 'O' } ;
  67. static char c_russian[] = { '@' ,'K' , 'F' , 'D' , 'C' , 'K' , 'P' } ;
  68.  
  69.  
  70. /* translation tables */
  71. char *in_table;
  72.  
  73.  
  74. char *  c_roque[] = { "O-O" , "O-O-O" , "o-o" , "o-o-o" , "0-0" , "0-0-0" };
  75.  
  76. /* various notations for en passant */
  77. #define N_EP 2
  78. char * c_en_passant[] = { "ep" , "e.p." } ;
  79.  
  80.  
  81. /* notation for catch */
  82. char c_prise ='x';
  83.  
  84. /* various comments */
  85. char * c_comments[] = { "+" , "++" , 
  86.               "?" , "??", "!", "!!", "!?", "?!",
  87.               "mate", "draw" };
  88.  
  89. /* movement tables */
  90. /* move only */
  91. /* white pawn, move */
  92. #define NB_M_PAWN_MOVE_WD 2
  93. static int m_pawn_move_wd [][2] = {
  94.   { 1, 0}, {2, 0}
  95. };
  96.  
  97. /* black pawn, move */
  98. #define NB_M_PAWN_MOVE_BD 2
  99. static int m_pawn_move_bd [][2] = {
  100.   {-1, 0}, {-2, 0}
  101. };
  102.  
  103. /* TRICK = we have added the catching move at the end of
  104.    the non catching ones; so in check_depl, we try first 
  105.    the non catching one and then the catching one.
  106.    So, even if catching (x) is non indicated in the input, 
  107.    we succeed in guessing the move
  108.    */
  109. /* white pawn, move */
  110. /*#define NB_M_PAWN_WD 2*/
  111. #define NB_M_PAWN_WD 4
  112. static int m_pawn_wd [][2] = {
  113.   { 1, 0}, {2, 0},
  114. /* catch... */
  115.   { 1, 1}, { 1,-1}
  116. };
  117.  
  118. /* white pawn, catch */
  119. #define NB_M_PAWN_WX 2
  120. static int m_pawn_wx [][2] = {
  121.   { 1, 1}, { 1,-1}
  122. };
  123.  
  124. /* black pawn, move */
  125. /*#define NB_M_PAWN_BD 2*/
  126. #define NB_M_PAWN_BD 4
  127. static int m_pawn_bd [][2] = {
  128.   {-1, 0}, {-2, 0},
  129. /* catch... */
  130.   {-1, 1}, {-1,-1} 
  131. };
  132.  
  133. /* black pawn, catch */
  134. #define NB_M_PAWN_BX 2
  135. static int m_pawn_bx [][2] = {
  136.   {-1, 1}, {-1,-1} 
  137. };
  138.  
  139.  
  140. #define NB_M_KNIGHT  8
  141. static int m_knight[][2] = { 
  142.   { 2, 1}, { 2,-1}, {-2, 1}, {-2,-1},
  143.   { 1, 2}, { 1,-2}, {-1, 2}, {-1,-2}
  144. };
  145.  
  146. #define NB_M_BISHOP 28
  147. static int m_bishop[][2] = {
  148.   { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
  149.   { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
  150.   {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
  151.   {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}
  152. };
  153.  
  154. #define NB_M_ROOK 28
  155. static int m_rook[][2] = {
  156.   { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
  157.   {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
  158.   { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
  159.   { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
  160. };
  161.  
  162. #define NB_M_QUEEN 56
  163. static int m_queen[][2] = {
  164.   { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
  165.   { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
  166.   {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
  167.   {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1},
  168.   { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
  169.   {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
  170.   { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
  171.   { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
  172. };
  173.  
  174. #define NB_M_KING 8
  175. static int m_king[][2] = {
  176.   { 1, 1}, { 1, 0}, { 1,-1},
  177.   {-1, 1}, {-1, 0}, {-1,-1},
  178.   { 0, 1}, { 0, -1}
  179. };
  180.  
  181.  
  182. /* I/O */
  183. FILE * infile ;
  184. FILE * fhelp;
  185.  
  186. static char * t_output[] = 
  187. { "ascii", "postscript", "tex", "roff", "xchess", "gnu" };
  188.  
  189.  
  190. /* ---------- automata definitions --------- */
  191. /* table for syntaxic analysis of move */
  192.  
  193. #define FINAL    10
  194. #define TML     FINAL   /* terminal state */
  195. #define NBETAT     11
  196. #define NBCLAS     8
  197.  
  198. /* successor of state */
  199. static int transit[NBETAT][NBCLAS] = { 
  200. /*   P a-h 1-8   -   x   =  \0   ? */ 
  201. /*(  0   1   2   3   4   5   6   7)*/
  202.   {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
  203.   { -1,  2, -1, -1,  4, -1, -1, -1 }, /* etat  1 */
  204.   { -1,  6,  3,  4,  4,  8,TML,TML }, /* etat  2 */
  205.   { -1,  6, -1,  4,  4,  8,TML,TML }, /* etat  3 */
  206.   {  5,  6, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
  207.   { -1,  6, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
  208.   { -1, -1,  7, -1, -1, -1, -1, -1 }, /* etat  6 */
  209.   { -1, -1, -1, -1, -1,  8,TML,TML }, /* etat  7 */
  210.   {  9, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
  211.   { -1, -1, -1, -1, -1, -1,TML,TML }, /* etat  9 */
  212.   { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 == terminal */
  213. };
  214.  
  215. /* actions to do */
  216. static int action[NBETAT][NBCLAS] = {
  217. /*   P a-h 1-8   -   x   =  \0   ? */ 
  218.   {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
  219.   { -1,  2, -1, -1, 10, -1, -1, -1 }, /* etat  1 */
  220.   { -1, 13,  3,  4,  5, 14,  6,  7 }, /* etat  2 */
  221.   { -1, 13, -1,  4,  5, 14,  6,  7 }, /* etat  3 */
  222.   {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
  223.   { -1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
  224.   { -1, -1,  3, -1, -1, -1, -1, -1 }, /* etat  6 */
  225.   { -1, -1, -1, -1, -1, 14,  8,  9 }, /* etat  7 */
  226.   { 15, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
  227.   { -1, -1, -1, -1, -1, -1, 17, 17 }, /* etat  9 */
  228.   { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 */
  229. };
  230.  
  231.  
  232.  
  233. /* current game
  234.    the name "tos" means "top of stack"
  235.    */
  236. static game * tos = GULL ;
  237.  
  238. /* array to see the king is in check
  239.    use in checkroque()
  240.    */
  241.  
  242.  
  243. /* booleen d'erreur */
  244. int error_flag = FALSE;
  245.  
  246.  
  247. /* move to display board */
  248. static int count = 0 ;
  249.  
  250.  
  251. static int move_to_display[NB_MOVE_TO_DISP] ;
  252. static int nb_move_to_dsp = 0;
  253. static int stop_at_display = FALSE;
  254.  
  255. /* variable holding current move */
  256. static depl * m = MULL ;
  257.  
  258. /* current move, used by the parser */
  259. static int curpiece,  curcol,  curlig ;
  260. static int curdigit, curmove;
  261.  
  262. static format * dr;
  263.  
  264. static int driver; /* driver type, ie gnu, ascii ... */
  265.  
  266. #define setboard(A,I,J,P,C) ({(A)->board[(I)][(J)] = (P) ; \
  267.                  (A)->color[(I)][(J)] = (C);})
  268. #define clsboard(A,I,J,P,C) ({(A)->board[(I)][(J)] = VOID ; \
  269.                 (A)->color[(I)][(J)] = VOID; }))
  270.  
  271. /* --------------------------- code part --------------------- */
  272.  
  273.  
  274. static int ispiece(c)
  275.      char c;
  276. {
  277.   register int i;
  278.   
  279.   for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  280.   /*(void) fprintf(stdout, "piece %d %c\n" , i , c);*/
  281.   return(i<NUMPIECES);
  282. }
  283.  
  284.  
  285. static int piece(c)
  286.      char c ;
  287. {
  288.   register int i;
  289.   
  290.   for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  291.   if ( i== NUMPIECES)
  292.     i = PAWN ;
  293.   return(i);
  294. }
  295.  
  296. /* this function return yhe # entry of a keyword in a given table.
  297.    if key is not present, it returns the default value
  298.    */
  299. static int find_keyword(tab, nbentry,defaut,key)
  300.      char * tab[];
  301.      int nbentry;
  302.      int defaut;
  303.      char *key;
  304. {
  305.   int i ;
  306.  
  307.   for(i=0; (i< nbentry) ;i++)
  308.     if (strcmp(tab[i],key)==0)
  309.       return(i);
  310.  
  311.   /* we failed to find the keyword */
  312.   (void) fprintf (stderr, "unknow keyword %s in this context\n",key);
  313.   return(defaut);
  314. }
  315.  
  316. /* ---------- board management function ------------- */
  317.  
  318. void clear_board(g)
  319.      game *g;
  320. {
  321.   register int i,j;
  322.  
  323.   for (i=0; i < 10; i++ )
  324.     for (j=0 ; j< 10 ; j++) {
  325.       g->board[i][j] = VOID;
  326.       g->color[i][j] = VOID;
  327.     }
  328. }
  329.  
  330. game * new_board()
  331. {
  332.   game * tmp;
  333.   int i; 
  334.  
  335.   tmp = (game *) malloc (sizeof(game));
  336.   ALLOCP(tmp);
  337.   /*for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
  338.     ((int *) tmp)[i] = 0;*/
  339.   return(tmp);
  340. }
  341.  
  342. void init_board(tgm)
  343.   game * tgm;
  344. {
  345.   register int i,j;
  346.  
  347.   clear_board(tgm);
  348.  
  349.   for (i=1; i< 9 ; i=i+7) {
  350.     tgm->board[i][1]= tgm->board[i][8] = ROOK ;
  351.     tgm->board[i][2]= tgm->board[i][7] = KNIGHT ;
  352.     tgm->board[i][3]= tgm->board[i][6] = BISHOP ;
  353.     tgm->board[i][4]= QUEEN;
  354.     tgm->board[i][5]= KING;
  355.   }
  356.   for (i=2; i< 8 ; i=i+5) 
  357.     for (j=1; j <=8 ; j++)
  358.       tgm->board[i][j] = PAWN;
  359.  
  360.   for (i=1; i <=2; i++)
  361.     for (j=1; j <=8 ; j++) {
  362.       tgm->color[i][j] = WHITE;
  363.       tgm->color[i+6][j] = BLACK ;
  364.     }
  365. }
  366.  
  367. depl * new_move()
  368. {
  369.   depl * tmp;
  370.   int i; 
  371.  
  372.   tmp = (depl *) malloc (sizeof(depl));
  373.   ALLOCP(tmp);
  374.   /*for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
  375.     ((int *) tmp)[i] = 0;*/
  376.   return(tmp);
  377. }
  378.  
  379.  
  380. void init_move(m)
  381.      depl *m;
  382. {
  383.   m->move= 1 ;
  384.   m->whiteturn = TRUE ;
  385. }
  386.      
  387. /* ----------- semantic evaluation of move ----------- */
  388. /* check if  position lies within the board
  389.    */
  390. int in_board(l,c)
  391.      int l,c;
  392. {
  393.   return ((c >= 1) && (c <= 8) && (l >= 1) && (l <= 8));
  394. }
  395.  
  396. /* check that the path from pos1 to pos2 is free
  397.    */
  398. int path_free(l1, c1, l2, c2)
  399. int l1,c1, l2, c2;
  400. {
  401.   int li = 1 ;
  402.   int ci = 1 ;
  403.   int lig, col;
  404.  
  405.  
  406.   li = SIGN(l2-l1);
  407.   ci = SIGN(c2-c1);
  408.  
  409.  
  410.   if ( c1 == c2 ) {    
  411.     col = c1;
  412.     for (lig = l1 +li; lig != l2 ; lig +=li)
  413.       if (tos->board[lig][col] != VOID)
  414.     return (FALSE);
  415.     return(TRUE);
  416.   }
  417.  
  418.   if ( l1 == l2) {
  419.     lig = l1 ;
  420.     for (col = c1 + ci; col != c2 ; col +=ci)
  421.       if (tos->board[lig][col] != VOID)
  422.     return (FALSE);
  423.     return(TRUE);
  424.   }
  425.  
  426.   for (lig = l1+li,col =c1+ci; (lig!=l2) && (col!=c2); lig+=li, col+= ci)
  427.     if (tos->board[lig][col] != VOID) {
  428.       return (FALSE);
  429.     }
  430.   return(TRUE);
  431. }
  432.  
  433. /* check roque is possible */
  434. int check_roque()
  435. {
  436.   int lig, col ;
  437.  
  438.   if (m->whiteturn)
  439.     lig = 1 ;
  440.   else
  441.     lig =8;
  442.   if (m->type == GRANDROQUE)
  443.     for (col = 2; col < 5 ; col++)
  444.       if (tos->board[lig][col] != VOID)
  445.     return(FALSE);
  446.   if (m->type == PETITROQUE)
  447.     for (col = 6; col < 7 ; col++)
  448.       if (tos->board[lig][col] != VOID)
  449.     return(FALSE);
  450.   if (m->is_check[CURCOLOR(m)])
  451.     return(FALSE);
  452.   return(TRUE);
  453. }
  454.   
  455. /* check -- or guess -- where a given piece come */
  456. int guess_piece() {return(tos->board[m->fromlig][m->fromcol]); }
  457.  
  458. /* try to guess the move -- low-level function */
  459. int guess_depl(nb, tab, pl1, pc1, l2,c2,path)
  460.      int nb;
  461.      int tab[][2];
  462.      int *pl1, *pc1;
  463.      int l2,c2;
  464.      int path;
  465. {
  466.   int i;
  467.   int c,l;
  468.  
  469.   for (i=0; i< nb; i++ ) {
  470.     l = l2 - tab[i][0];
  471.     c = c2 - tab[i][1];
  472.     if (in_board(l,c))
  473.       if ((tos->board[l][c] == m->piece) &&
  474.       (tos->color[l][c] == CURCOLOR(m)) &&
  475.       ( !path || (path && path_free(l,c, l2, c2))) &&
  476.       ( ((*pl1) == 0) || ((*pl1) == l) ) &&
  477.       ( ((*pc1) == 0) || ((*pc1) == c) ) )
  478.       {
  479.     *pl1 = l;
  480.     *pc1 = c;
  481.     return(TRUE);
  482.       }
  483.   }
  484.   return(FALSE);
  485. }
  486.  
  487. /* check for ambiguitey in a move
  488.    used in ouptut function: the piece had beenm already moved and
  489.    if we guess another move, there is an ambiguity
  490.    */
  491. int ambiguity(frompiece, l2, c2)
  492.      int frompiece, l2, c2 ;
  493. {
  494.   int l1 = 0 ;
  495.   int c1 = 0 ;
  496.  
  497.   switch(frompiece) {
  498.   case PAWN:
  499.     if (m->type == PRISE) {
  500.       if (m->whiteturn)
  501.     return(guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE));
  502.       else
  503.     return(guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE));
  504.    } else {
  505.       if (m->whiteturn)
  506.     return(guess_depl(NB_M_PAWN_MOVE_WD, m_pawn_move_wd, 
  507.               &l1,&c1, l2,c2, FALSE));
  508.       else
  509.     return(guess_depl(NB_M_PAWN_MOVE_BD, m_pawn_move_bd, 
  510.               &l1,&c1, l2,c2, FALSE));
  511.     }
  512.     /* break; */
  513.   case KNIGHT:
  514.     return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
  515.     /* break; */
  516.   case BISHOP:
  517.     return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
  518.     /* break; */
  519.   case ROOK:
  520.     return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
  521.     /* break; */
  522.   case QUEEN:
  523.     return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
  524.     /* break; */
  525.   case KING:
  526.     return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
  527.     /* break; */
  528.   default:
  529.     break;
  530.   }
  531.   return(TRUE);
  532. }
  533.  
  534. int check_move(m)
  535.      depl * m;
  536. {
  537.   int l1,c1,l2,c2,l;
  538.   int tmp; /* tmp boolean */
  539.  
  540.   l1 = m->fromlig;
  541.   c1 = m->fromcol;
  542.   l2 = m->tolig;
  543.   c2 = m->tocol;
  544.  
  545.   if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  546.     return(check_roque());
  547.  
  548.   if ((tos->board[l1][c1] != m->piece)||
  549.       (tos->color[l1][c1] != CURCOLOR(m))){
  550.     printf("==%d\n",tos->board[l1][c1]);
  551.     error ((stderr,"from position and piece not correct\n"));
  552.     return(FALSE);
  553.   }
  554.  
  555.   /* if prise === FALSE, we must not take a piece */
  556.   if (tos->board[l2][c2] != VOID 
  557.       && (m->type != PRISE) && (m->type != PROM_ET_PRISE)) {
  558.     (void) fprintf(stderr,"catching not indicated at move %d\n",m->move);
  559.     return(FALSE);
  560.   }
  561.  
  562.   /* prendre une de ses propres pieces */
  563.   if (tos->color[l2][c2] == tos->color[l1][c1] && m->prise) {
  564.     (void) fprintf(stderr,"attempt to catch same color piece at move %d\n",
  565.            m->move);
  566.     return(FALSE);
  567.   }
  568.  
  569.   /* we check if the move is a possible one for the piece
  570.      */
  571.  
  572.   switch(m->piece) {
  573.   case PAWN:
  574.     if (m->prise) {
  575.       if (m->whiteturn)
  576.     tmp = guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  577.       else
  578.     tmp = guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  579.    } else {
  580.       if (m->whiteturn)
  581.     tmp = guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE);
  582.       else
  583.     tmp = guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE);
  584.     }
  585.     /* is it a "prise en passant " */
  586.     if ((c1 != c2) && (tos->board[l2][c2] == VOID)
  587.     && (tos->board[l1][c2] == PAWN)) {
  588.       m->type = EN_PASSANT ;
  589.       l = l1 + (l2 - l1)/2;
  590.       /* we must perform here the "en passant" test */
  591.       tos->board[l1][c2] = VOID ;
  592.       tos->color[l1][c2] = VOID ;
  593.       tmp = TRUE;
  594.     }
  595.     return(tmp);
  596.     /* break; */
  597.   case KNIGHT:
  598.     return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
  599.     /* break; */
  600.   case BISHOP:
  601.     return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
  602.     /* break; */
  603.   case ROOK:
  604.     return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
  605.     /* break; */
  606.   case QUEEN:
  607.     return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
  608.     /* break; */
  609.   case KING:
  610.     return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
  611.     /* break; */
  612.   default:
  613.     break;
  614.   }
  615.  
  616.   return(TRUE);
  617. }
  618.  
  619. /* try to guess the move -- used for shortened notation
  620.    */
  621. int guess_move()
  622. {
  623.   int l1,c1,l2,c2;
  624.  
  625.   if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  626.     return(TRUE);
  627.  
  628.   l1 = m->fromlig ;
  629.   c1 = m->fromcol ;
  630.   l2 = m->tolig;
  631.   c2 = m->tocol;
  632.  
  633.   switch(m->piece) {
  634.   case PAWN:
  635.     if (m->prise) {
  636.       if (m->whiteturn)
  637.     (void) guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  638.       else
  639.     (void) guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  640.     } else {
  641.       if (m->whiteturn)
  642.     (void) guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE); 
  643.       else
  644.     (void) guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE); 
  645.     }
  646.     break;
  647.   case KNIGHT:
  648.     (void) guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE);
  649.     break;
  650.   case BISHOP:
  651.     (void) guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE);
  652.     break;
  653.   case ROOK:
  654.     (void) guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE);
  655.     break;
  656.   case QUEEN:
  657.     (void) guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE);
  658.     break;
  659.   case KING:
  660.     (void) guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE);
  661.     break;
  662.   default:
  663.     break;
  664.   }
  665.  
  666.   if ((l1 == 0) || (c1 == 0)) {
  667.     if (m->whiteturn)
  668.       error((stderr,"unable to guess move %d white (%d)\n",
  669.          m->move,m->piece));
  670.     else
  671.       error((stderr,"unable to guess move %d black (%d)\n",
  672.          m->move,m->piece));
  673.     return(FALSE);
  674.   } else {
  675.     m->fromcol = c1;
  676.     m->fromlig = l1;
  677.     return(TRUE);
  678.   }
  679. }
  680.  
  681. /* --------------- execution of move ----------------- */
  682.  
  683. /* clear a position */
  684. int clear_pos(lig,col)
  685.      int lig;
  686.      int col;
  687. {
  688.   tos->board[lig][col] = VOID ;
  689.   tos->color[lig][col] = VOID ;
  690.   return(TRUE);
  691. }
  692.  
  693. /* configure the board */
  694. int configure()
  695. {
  696.   if (configuring) {
  697.     if (m->piece == VOID)
  698.       m->piece = PAWN ;
  699.     tos->board[m->tolig][m->tocol] = m->piece ;
  700.     tos->color[m->tolig][m->tocol] = configside ;
  701.   }
  702.   return(TRUE);
  703. }
  704.  
  705. /* execute a move, no checking */
  706. int execute_move()
  707. {
  708.   register int i;
  709.  
  710.   if (m->piece == VOID )
  711.     m->piece = PAWN;
  712.  
  713.   if ((m->fromlig == 0) || (m->fromcol == 0))
  714.     (void) guess_move();
  715.   
  716.   /* supply to the -- maybe -- deficiency of input notation
  717.      */
  718.   if ((m->fromlig !=0) || (m->fromcol != 0))
  719.     m->piece = tos->board[m->fromlig][m->fromcol];
  720.  
  721.   if (tos->board[m->tolig][m->tocol] != VOID) {
  722.     m->type = PRISE;
  723.     m->prise = tos->board[m->tolig][m->tocol] ;
  724.   }
  725.  
  726.   if (!check_move(m)) {
  727.     if (m->whiteturn)
  728.       error((stderr,"white move %d illegal\n",m->move));
  729.     else
  730.       error((stderr,"black move %d illegal\n",m->move));
  731.   }
  732.  
  733.   if (m->type == PETITROQUE) {
  734.     if (m->whiteturn)
  735.       curlig = 1 ;
  736.     else
  737.       curlig = 8 ;
  738.     tos->board[curlig][7] = KING;
  739.     tos->board[curlig][6] = ROOK;
  740.     tos->color[curlig][7] = tos->color[curlig][5] ;
  741.     tos->color[curlig][6] = tos->color[curlig][5] ;
  742.     (void) clear_pos(curlig, 5);
  743.     (void) clear_pos(curlig, 8);
  744.   }
  745.   if (m->type == GRANDROQUE) {
  746.     if (m->whiteturn)
  747.       curlig = 1 ;
  748.     else
  749.       curlig = 8 ;
  750.     tos->board[curlig][3] = KING;
  751.     tos->board[curlig][4] = ROOK;
  752.     tos->color[curlig][3] = tos->color[curlig][5] ;
  753.     tos->color[curlig][4] = tos->color[curlig][5] ;
  754.     (void) clear_pos(curlig, 5);
  755.     (void) clear_pos(curlig, 1);
  756.   }
  757.  
  758.         
  759.   if (!(m->type == GRANDROQUE) || (m->type == PETITROQUE)) {
  760.     if (m->piece == VOID)
  761.       m->piece = tos->board[m->fromlig][m->fromcol];
  762.     /*if (m->topiece == VOID)
  763.       m->topiece = tos->board[m->fromlig][m->fromcol];*/
  764.     tos->board[m->tolig][m->tocol] = tos->board[m->fromlig][m->fromcol];
  765.     tos->color[m->tolig][m->tocol] = tos->color[m->fromlig][m->fromcol];
  766.     (void) clear_pos(m->fromlig,m->fromcol);
  767.   }
  768.   
  769.   if ((m->type == PROMOTION) || (m->type == PROM_ET_PRISE))
  770.     tos->board[m->tolig][m->tocol] = m->promotion ;
  771.      
  772.   output_move(dr,m);
  773.  
  774.   if (error_flag) {
  775.     (void) fprintf(dr->outfile, "\nlast position encountered:\n");
  776.     output_board(dr,tos);
  777.     close_files();
  778.     exit(0);
  779.   }
  780.  
  781.   /* do we need to display the move ? */
  782.   if (nb_move_to_dsp > 0) {
  783.     for (i=0; i < nb_move_to_dsp; i++)
  784.       if (m->move == (move_to_display[i] ) && !m->whiteturn ) {
  785.     output_board(dr,tos);
  786.     if (stop_at_display) {
  787.       output_end(dr);
  788.       close_files();
  789.       exit(0);
  790.     }
  791.       }
  792.   }
  793.  
  794.   return(TRUE);
  795. }
  796.  
  797. /* ------------------ automata ----------------------- */
  798.  
  799. /* categorise the input for the automata */
  800. int typechar(c)
  801.      char c;
  802. {
  803.   if (ispiece(c))
  804.     return(0);
  805.   if ((c >=  'a') && ( c <= 'h'))
  806.     return(1);
  807.   if ((c >=  '1') && ( c <= '8'))
  808.     return(2);
  809.   if ( c== '-' )
  810.     return(3);
  811.   if ((c == 'x') || (c == 'X' ))
  812.     return(4);
  813.   if (c == '=' )
  814.     return(5);
  815.   if (c == '\0' )
  816.     return(6);
  817.   return(7);
  818. }
  819.  
  820.  
  821. /* execute the actions decided by the automata */
  822. int execute(num,c)
  823.      int num;
  824.      char c;
  825. {
  826.   switch (num) {
  827.   case 1: /* set cur piece */
  828.     curpiece = piece(c);
  829.     break;
  830.   case 2: /* set cur col */
  831.     curcol = lettertocol(c);
  832.     break;
  833.   case 3: /* set cur lig */
  834.     curlig = lettertolig(c);
  835.     break;
  836.   case 4: /* from = cur ; prise = false */
  837.     m->piece = curpiece ;
  838.     m->fromcol = curcol ;
  839.     m->fromlig = curlig;
  840.     /*m->topiece = curpiece;*/
  841.     break;
  842.   case 5: /* from = cur ; prise = true */
  843.     m->piece = curpiece ;
  844.     m->fromcol = curcol ;
  845.     m->fromlig = curlig;
  846.     m->type = PRISE ;
  847.     m->prise = curpiece;
  848.     break;
  849.   case 6: /* to = cur ; guess from */
  850.   case 7: /* to = cur ; guess from ; parse remaining token */
  851.     m->piece = curpiece ;
  852.     m->tocol = curcol;
  853.     m->tolig = curlig ;
  854.  
  855.     /*m->topiece = curpiece ; /* ? */
  856.  
  857.     if (configuring)
  858.       (void) configure();
  859.     else {
  860.       (void) execute_move();
  861.       m->whiteturn = !m->whiteturn ; 
  862.       if (m->whiteturn) m->move++ ;
  863.     }
  864.     break;
  865.   case 8: /* to = cur */
  866.   case 9: /* to = cur */
  867.     m->tocol = curcol;
  868.     m->tolig = curlig ;
  869.     /*m->topiece = curpiece ;*/
  870.  
  871.     if (configuring)
  872.       (void) configure();
  873.     else {
  874.       (void) execute_move();
  875.       m->whiteturn = !m->whiteturn ; 
  876.       if (m->whiteturn) m->move++ ;
  877.     }
  878.     break;
  879.   case 10: /* piece = cur piece ; prise = true */
  880.     /* later : guess from position */
  881.     m->piece = curpiece ;
  882.     m->type = PRISE ;
  883.     break;
  884.   case 11: /* grand roque */
  885.   case 12: /* petit roque */
  886.  
  887.     (void) execute_move();
  888.  
  889.     m->whiteturn = !m->whiteturn ; 
  890.     if (m->whiteturn) m->move++ ;
  891.     break;
  892.   case 13: /* case of simpliest algebraic notation ;
  893.           only e2e4 : this is the transition from e2 to e4
  894.           also the case of move such as Nge2
  895.           from =cur; prise = FALSE;
  896.           also:
  897.           curcol = ...
  898.           */
  899.     m->piece = curpiece ;
  900.     m->fromcol = curcol ;
  901.     m->fromlig = curlig;
  902.     /*m->topiece = curpiece;*/
  903.     m->type = MOVE;
  904.     curcol = lettertocol(c);
  905.   case 14: /* promotion, the "=" */
  906.     break;
  907.   case 15: /* promotion, the piece name */
  908.     /* to = cur ; guess from */
  909.   case 16: 
  910.     /* to = cur */
  911.  
  912.     m->tocol = curcol;
  913.     m->tolig = curlig ;
  914.     /*m->topiece = curpiece ;*/
  915.  
  916.     if (m->type == PRISE )
  917.       m->type = PROM_ET_PRISE ;
  918.     else
  919.       m->type = PROMOTION ;
  920.     m->promotion = curpiece = piece(c) ;
  921.  
  922.     break;
  923.   case 17: /* execute move for promotion */
  924.     (void) execute_move();
  925.  
  926.     m->whiteturn = !m->whiteturn ; 
  927.     if (m->whiteturn) m->move++ ;
  928.     break;
  929.   case -1:
  930.     break;
  931.   default:
  932.     break;
  933.   }
  934.   return(TRUE);
  935. }
  936.  
  937. int parse_number(token)
  938.      char *token;
  939. {
  940.   int curmove = 0 ;
  941.   int i;
  942.  
  943.   /* check coherency with internal numbering */
  944.   i = 0;
  945.   while (isdigit(token[i])) {
  946.    curmove = curmove * 10 +  ((int) token[i++] - (int) '0' );
  947.   }
  948.   if (curmove != m->move)
  949.     (void) fprintf(stderr,"problem in move numbering: %d vs %d\n",
  950.            m->move, curmove);
  951.   return(TRUE);
  952. }
  953.  
  954. int parse_keyword(token)
  955.      char *token;
  956. {
  957.   char c;
  958.  
  959.   switch (find_keyword(keywords, NBKEYWORD, KNULL, token)) {
  960.   case START:
  961.     configuring = FALSE;
  962.     m->move = 1;
  963.     m->whiteturn = TRUE;
  964.     break;
  965.   case CLEAR:
  966.     clear_board(tos);
  967.     break;
  968.   case SHOWBOARD:
  969.     output_board(dr,tos);
  970.     break;
  971.   case TOWHITE:
  972.     m->move = 1;
  973.     m->whiteturn = TRUE;
  974.     break;
  975.   case TOBLACK:
  976.     m->move = 1;
  977.     m->whiteturn = FALSE;
  978.     break;
  979.   case CONFIGWH:
  980.     configuring = TRUE ;
  981.     configside = WHITE;
  982.     break;
  983.   case CONFIGBL:
  984.     configuring = TRUE ;
  985.     configside = BLACK;
  986.     break;
  987.   case DEFAULTP:
  988.     init_board(tos);
  989.     break;
  990.   case SPECIAL: /* all input, up to \n is copied to output */
  991.     while ((( c = getc(infile)) != EOF) && (c != '\n'))
  992.       (void) putc (c,dr->outfile);
  993.     putc ('\n', dr->outfile);
  994.     break;
  995.   case KNULL:
  996.   default:
  997.     break;
  998.   }
  999.   return(TRUE);
  1000. }
  1001.  
  1002. int parse_roque(token)
  1003.      char * token;
  1004.   int i;
  1005.  
  1006.   for (i=0; i < NBROQUE && (strcmp(c_roque[i],token)!=0); i++) ;
  1007.   if ( i < NBROQUE ) {
  1008.     if (strlen(token) == 3) {
  1009.       m->type = PETITROQUE ;
  1010.       (void) execute(12,DUMMYCHAR);
  1011.     } else {
  1012.       m->type = GRANDROQUE ;
  1013.       (void) execute(11,DUMMYCHAR);
  1014.     }
  1015.     /*(void) fprintf(stderr,"ROQUE\n");*/
  1016.     return(TRUE);
  1017.   }
  1018.  
  1019.   return(FALSE);
  1020. }
  1021.  
  1022. int  parse_move(token)
  1023.      char *token;
  1024. {
  1025.   register int i;
  1026.   int correcte = FALSE ;
  1027.   int erreursyntaxe = FALSE ;
  1028.   int etat =0;
  1029.   int code;
  1030.   
  1031.   i=0;
  1032.   while ( !correcte && !erreursyntaxe ) {
  1033.     code = typechar(token[i]);
  1034.     (void) execute(action[etat][code],token[i]);
  1035.     etat = transit[etat][code] ;
  1036.     if (etat == -1) 
  1037.       erreursyntaxe = TRUE;
  1038.     if (etat == FINAL)
  1039.       correcte = TRUE ;
  1040.     i++;
  1041.   }
  1042.   if (erreursyntaxe) {
  1043.     (void) fprintf(stderr, "no comprende, senor: %s\n",token);
  1044.     return(FALSE);
  1045.   }
  1046.   if (correcte) {
  1047.     /*(void) fprintf(stderr, "ia panimaiou, davai\n");*/
  1048.   }
  1049.   return(TRUE);
  1050. }
  1051.  
  1052. void init_parse(m)
  1053.      depl * m ;
  1054. {
  1055.   int i;
  1056.  
  1057.   /* global position and piece variable initialised to 0
  1058.      */
  1059.   /* move and whiteturn unchanged */ 
  1060.  
  1061.   m->type = MOVE ;
  1062.  
  1063.   curpiece = m->piece = VOID ;
  1064.   curcol = m->tocol = m->fromcol = 0;
  1065.   curlig = m->tolig = m->fromlig = 0;
  1066.  
  1067.   m->promotion = VOID;
  1068.   m->prise = VOID;
  1069.  
  1070.   for (i=0; i< 3; i++)
  1071.     m->is_check[i] = FALSE ;
  1072.   curdigit = curmove = 0;
  1073. }
  1074.  
  1075. /* ------------------- top routines -------------------- */
  1076.  
  1077. /* cette fonction analyse les arguments de la ligne de commande
  1078.    */
  1079. int parse_options(argc,argv)
  1080.      int argc;
  1081.      char * argv[];
  1082. {
  1083.   int narg =1 ;
  1084.   int i;
  1085.   register int c;
  1086.   char cp[132];
  1087.   char chaine[MAXTOKLEN];
  1088.  
  1089.   infile = stdin;
  1090.   dr->outfile = stdout;
  1091.   nb_move_to_dsp = 0;
  1092.  
  1093.   while (narg < argc ) {
  1094.     (void) strcpy (cp,argv[narg]);
  1095.     switch (cp[0]) {
  1096.     case '-' :
  1097.       switch (cp[1]) {
  1098.       case 'f' : /* from langage */
  1099.     if  ((narg+1) >= argc )
  1100.       fatal((stderr,"missing argument to %s option",cp));
  1101.     narg++ ;
  1102.     in_language = find_keyword (t_language, NBLANGUAGE,
  1103.                     DEFAULT_INPUT_LANGUAGE,
  1104.                     argv[narg]);
  1105.     break;
  1106.       case 't' : /* to langage */
  1107.     if  ((narg+1) >= argc )
  1108.       fatal((stderr,"missing argument to %s option",cp));
  1109.     narg++ ;
  1110.     out_language = find_keyword (t_language, NBLANGUAGE,
  1111.                      DEFAULT_OUTPUT_LANGUAGE,
  1112.                      argv[narg]);
  1113.     break;
  1114.       case 'o' : /* next arg is output file */
  1115.     narg++ ;
  1116.     if ((dr->outfile = fopen (argv[narg],"w+")) == NULL) {
  1117.       (void) fprintf (stderr,"can't open %s output file\n",argv[narg]);
  1118.       (void) fprintf (stderr,"assume stdout for output\n");
  1119.     }
  1120.     break;
  1121.       case 'e':
  1122.     if  ((narg+1) >= argc )
  1123.       fatal((stderr,"missing argument to %s option",cp));
  1124.     narg++ ;
  1125.  
  1126.     i=0;
  1127.     nb_move_to_dsp = 0;
  1128.     move_to_display[nb_move_to_dsp] = 0;
  1129.     while (isdigit(argv[narg][i])) {
  1130.       move_to_display[nb_move_to_dsp] =
  1131.         ((int) argv[narg][i] - (int) '0')
  1132.           + move_to_display[nb_move_to_dsp] * 10;
  1133.       i++;
  1134.     }
  1135.     nb_move_to_dsp++;
  1136.     stop_at_display = TRUE;
  1137.     break;
  1138.       case 'c':
  1139.     if  ((narg+1) >= argc )
  1140.       fatal((stderr,"missing argument to %s option",cp));
  1141.     narg++ ;
  1142.  
  1143.     i=0;
  1144.     while (isdigit(argv[narg][i])) {
  1145.       move_to_display[nb_move_to_dsp] = 0;
  1146.       while (isdigit(argv[narg][i])) {
  1147.         move_to_display[nb_move_to_dsp] =
  1148.           ((int) argv[narg][i] - (int) '0')
  1149.           + move_to_display[nb_move_to_dsp] * 10;
  1150.         i++;
  1151.       }
  1152.       nb_move_to_dsp++;
  1153.  
  1154.       if (nb_move_to_dsp > NB_MOVE_TO_DISP)
  1155.         fatal((stderr,"max. number of move to display exceeded"));
  1156.  
  1157.       /* process next number */
  1158.       if (argv[narg][i] == ',')
  1159.         i++;
  1160.     }
  1161.     break;
  1162.       case 'a': /* algebraic output */
  1163.     dr->output_move_format = ALGEBRAIC;
  1164.     break;
  1165.       case 's':  /* shortened output */
  1166.     dr->output_move_format = SHORTENED;
  1167.     break;
  1168.       case 'b': /* display only the board, no move */
  1169.     dr->only_board = TRUE;
  1170.     break;
  1171.       case 'd': /* output driver */
  1172.     if  ((narg+1) >= argc )
  1173.       fatal((stderr,"missing argument to %s option",cp));
  1174.     narg++ ;
  1175.     driver = find_keyword(t_output, NB_DRIVER, DEFAULT_DRIVER,
  1176.                   argv[narg]);
  1177.     break;
  1178.       case 'h': /* help file */
  1179.     (void) strcpy(chaine,LIB_DIR);
  1180.         if ((fhelp = fopen(strcat(chaine,HELP_FILE),"r")) == NULL)
  1181.           fatal((stderr,"Can't find help file.\n"));
  1182.         else {
  1183.           while ((c = getc(fhelp)) != EOF)
  1184.             (void) fputc(c,stderr);
  1185.           (void) fclose(fhelp);
  1186.       exit(0);
  1187.         }
  1188.          break;
  1189.       default:
  1190.     error((stderr,"unknown command line options %s\n",cp));
  1191.     break;
  1192.       }
  1193.       break;
  1194.     default: /* assume this is the input file */
  1195.       if ((infile = fopen (cp,"r")) == NULL)
  1196.     fatal((stderr,"can't open %s input file\n",cp));
  1197.     }
  1198.     narg++;
  1199.   } /* process next arg */
  1200.   return(argc);
  1201. }
  1202.  
  1203. void close_files()
  1204. {
  1205.   if (infile != stdin )
  1206.     (void) fclose(infile);
  1207.   if (dr->outfile != stdout )
  1208.     (void) fclose(dr->outfile);
  1209. }
  1210.  
  1211. int associe_traduction (table, langage)
  1212. char ** table;
  1213. int langage ;
  1214. {
  1215.   switch (langage) {
  1216.   case FRENCH :
  1217.     *table = c_french ;
  1218.     break;
  1219.   case ENGLISH:
  1220.     *table = c_english ;
  1221.     break;
  1222.   case ITALIAN:
  1223.     *table = c_italian ;
  1224.     break;
  1225.   case SPANISH:
  1226.     *table = c_spanish ;
  1227.     break;
  1228.   case GERMAN:
  1229.     *table = c_german ;
  1230.     break;
  1231.   case DUTCH:
  1232.     *table = c_dutch ;
  1233.     break;
  1234.   case RUSSIAN:
  1235.     (void) fprintf(stderr,"russian not yet implemented\n");
  1236.     *table = c_russian ;
  1237.     break;
  1238.   default:
  1239.     error((stderr,"unknown langage\n"));
  1240.   }
  1241.   return(langage);
  1242. }
  1243.  
  1244. /* ------------- main --------------------- */
  1245.  
  1246. main(argc,argv)
  1247.      int argc;
  1248.      char * argv[];
  1249. {
  1250.   (void) fprintf(stderr,"%s\n",version_string);
  1251.   
  1252.   /* allocation of driver descriptor */
  1253.   dr = new_driver();
  1254.  
  1255.   /* default configuration */
  1256.   init_driver(dr,DEFAULT_DRIVER);
  1257.   (void) associe_traduction(&in_table,  DEFAULT_INPUT_LANGUAGE );
  1258.   (void) associe_traduction(&(dr->out_table), DEFAULT_OUTPUT_LANGUAGE);
  1259.  
  1260.   (void) parse_options(argc,argv);
  1261.  
  1262.   (void) associe_traduction (&in_table, in_language);
  1263.   (void) associe_traduction (&(dr->out_table), out_language);
  1264.  
  1265.   /* assoc driver */
  1266.   init_driver(dr,driver);
  1267.  
  1268.   configuring = FALSE;
  1269.   configside = VOID;
  1270.  
  1271.   /* initialise output file */
  1272.   output_init(dr);
  1273.  
  1274.   if (error_flag)
  1275.     fatal((stderr,"too many errors"));
  1276.  
  1277.   /* allocation of move descriptor */
  1278.   m = new_move();
  1279.   init_move(m);
  1280.   
  1281.   /* allocation of board descriptor */
  1282.   tos = new_board();
  1283.   init_board(tos);
  1284.  
  1285.   /*output_board(dr,tos);*/
  1286.  
  1287.   while (nexttoken()) {
  1288.     /*(void) fprintf(stdout,"%s%\n", curtok);*/
  1289.     init_parse(m);
  1290.     (void) parsetoken();
  1291.   }
  1292.   if ((count == 0) && !error_flag)
  1293.     output_board(dr,tos);
  1294.  
  1295.   if (error_flag) {
  1296.     error((stderr,"last valid position:\n"));
  1297.     output_board(dr,tos);
  1298.     fatal((stderr,"too many errors"));
  1299.   }
  1300.  
  1301.   /* terminates output files */
  1302.   output_end(dr);
  1303.  
  1304.   /* close files */
  1305.   close_files();
  1306.  
  1307.   /* exit properly */
  1308. #ifdef TURBOC
  1309.   return(TRUE);
  1310. #else
  1311.   exit(0);
  1312. #endif
  1313. }
  1314.