10 static void out_CSA_header( const tree_t * restrict ptree, record_t *pr );
11 static int str2piece( const char *str );
12 static int skip_comment( record_t *pr );
13 static int read_char( record_t *pr );
14 static int read_CSA_line( record_t *pr, char *str );
15 static int in_CSA_header( tree_t * restrict ptree, record_t *pr, int flag );
16 static int read_board_rep2( const char *str_line, min_posi_t *pmin_posi );
17 static int read_board_rep3( const char *str_line, min_posi_t *pmin_posi );
20 read_record( tree_t * restrict ptree, const char *str_file,
21 unsigned int moves, int flag )
26 iret = record_open( &record, str_file, mode_read, NULL, NULL );
27 if ( iret < 0 ) { return iret; }
31 iret = in_CSA_header( ptree, &record, flag );
34 record_close( &record );
39 iret = in_CSA( ptree, &record, NULL, flag );
42 record_close( &record );
45 } while ( iret != record_next
47 && moves > record.moves );
49 return record_close( &record );
54 record_open( record_t *pr, const char *str_file, record_mode_t record_mode,
55 const char *str_name1, const char *str_name2 )
57 pr->games = pr->moves = pr->lines = 0;
58 pr->str_name1[0] = '\0';
59 pr->str_name2[0] = '\0';
63 strncpy( pr->str_name1, str_name1, SIZE_PLAYERNAME-1 );
64 pr->str_name1[SIZE_PLAYERNAME-1] = '\0';
69 strncpy( pr->str_name2, str_name2, SIZE_PLAYERNAME-1 );
70 pr->str_name2[SIZE_PLAYERNAME-1] = '\0';
73 if ( record_mode == mode_write )
75 pr->pf = file_open( str_file, "w" );
76 if ( pr->pf == NULL ) { return -2; }
78 else if ( record_mode == mode_read_write )
80 pr->pf = file_open( str_file, "wb+" );
81 if ( pr->pf == NULL ) { return -2; }
84 assert( record_mode == mode_read );
86 pr->pf = file_open( str_file, "rb" );
87 if ( pr->pf == NULL ) { return -2; }
95 record_close( record_t *pr )
97 int iret = file_close( pr->pf );
104 out_CSA( tree_t * restrict ptree, record_t *pr, unsigned int move )
106 const char *str_move;
110 if ( move == MOVE_RESIGN )
112 if ( ! pr->moves ) { out_CSA_header( ptree, pr ); }
113 fprintf( pr->pf, "%s\n", str_resign );
119 root_turn = Flip(root_turn);
120 UnMakeMove( root_turn, move, 1 );
121 out_CSA_header( ptree, pr );
122 MakeMove( root_turn, move, 1 );
123 root_turn = Flip(root_turn);
125 str_move = str_CSA_move( move );
126 fprintf( pr->pf, "%c%s\n", ach_turn[Flip(root_turn)], str_move );
132 sec = root_turn ? sec_b_total : sec_w_total;
134 fprintf( pr->pf, "T%-7u,'%03u:%02u \n", sec_elapsed, sec / 60U, sec % 60U );
137 /* print repetition or mate status */
138 if ( game_status & flag_mated )
140 fprintf( pr->pf, "%%TSUMI\n" );
143 else if ( game_status & flag_drawn )
145 fprintf( pr->pf, "%s\n", str_repetition );
154 record_wind( record_t *pr )
156 char str_line[ SIZE_CSALINE ];
160 iret = read_CSA_line( pr, str_line );
161 if ( iret < 0 ) { return iret; }
162 if ( ! iret ) { return record_eof; }
163 if ( ! strcmp( str_line, "/" ) ) { break; }
171 #if ! defined(MINIMUM)
173 record_rewind( record_t *pr )
175 pr->games = pr->moves = pr->lines = 0;
176 if ( fseek( pr->pf, 0, SEEK_SET ) ) { return -2; }
183 record_getpos( record_t *pr, rpos_t *prpos )
185 if ( fgetpos( pr->pf, &prpos->fpos ) )
187 str_error = "fgetpos() failed.";
190 prpos->games = pr->games;
191 prpos->moves = pr->moves;
192 prpos->lines = pr->lines;
199 record_setpos( record_t *pr, const rpos_t *prpos )
201 if ( fsetpos( pr->pf, &prpos->fpos ) )
203 str_error = "fsetpos() failed.";
206 pr->games = prpos->games;
207 pr->moves = prpos->moves;
208 pr->lines = prpos->lines;
212 #endif /* no MINIMUM */
216 in_CSA( tree_t * restrict ptree, record_t *pr, unsigned int *pmove, int flag )
218 char str_line[ SIZE_CSALINE ];
224 if ( pr->moves == 0 )
226 iret = in_CSA_header( ptree, pr, flag );
227 if ( iret < 0 ) { return iret; }
231 iret = read_CSA_line( pr, str_line );
232 if ( iret < 0 ) { return iret; }
233 if ( ! iret ) { return record_eof; }
234 if ( ! strcmp( str_line, str_resign ) )
236 game_status |= flag_resigned;
237 return record_resign;
239 if ( ! strcmp( str_line, str_repetition )
240 || ! strcmp( str_line, str_jishogi ) )
242 game_status |= flag_drawn;
245 if ( ! strcmp( str_line, str_record_error ) )
249 } while ( str_line[0] == 'T' || str_line[0] == '%' );
251 if ( ! strcmp( str_line, "/" ) )
258 if ( game_status & mask_game_end )
260 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
261 pr->lines, str_bad_record );
262 str_error = str_message;
266 iret = interpret_CSA_move( ptree, &move, str_line+1 );
269 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
270 pr->lines, str_error );
271 str_error = str_message;
274 if ( pmove != NULL ) { *pmove = move; }
277 if ( flag & flag_time )
279 iret = read_CSA_line( pr, str_line );
280 if ( iret < 0 ) { return iret; }
283 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
284 pr->lines, str_unexpect_eof );
285 str_error = str_message;
288 if ( str_line[0] != 'T' )
290 snprintf( str_message, SIZE_MESSAGE, str_fmt_line, pr->lines,
291 "Time spent is not available." );
292 str_error = str_message;
295 l = strtol( str_line+1, &ptr, 0 );
296 if ( ptr == str_line+1 || l == LONG_MAX || l < 0 )
298 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
299 pr->lines, str_bad_record );
300 str_error = str_message;
305 sec_elapsed = (unsigned int)l;
306 if ( root_turn ) { sec_w_total += (unsigned int)l; }
307 else { sec_b_total += (unsigned int)l; }
309 iret = make_move_root( ptree, move, flag & ~flag_time );
312 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
313 pr->lines, str_error );
314 str_error = str_message;
325 interpret_CSA_move( tree_t * restrict ptree, unsigned int *pmove,
328 int ifrom_file, ifrom_rank, ito_file, ito_rank, ipiece;
331 unsigned int *pmove_last;
334 ifrom_file = str[0]-'0';
335 ifrom_rank = str[1]-'0';
336 ito_file = str[2]-'0';
337 ito_rank = str[3]-'0';
339 ito_file = 9 - ito_file;
340 ito_rank = ito_rank - 1;
341 ito = ito_rank * 9 + ito_file;
342 ipiece = str2piece( str+4 );
345 str_error = str_illegal_move;
349 if ( ! ifrom_file && ! ifrom_rank )
351 move = To2Move(ito) | Drop2Move(ipiece);
355 ifrom_file = 9 - ifrom_file;
356 ifrom_rank = ifrom_rank - 1;
357 ifrom = ifrom_rank * 9 + ifrom_file;
358 if ( abs(BOARD[ifrom]) + promote == ipiece )
365 move |= ( To2Move(ito) | From2Move(ifrom) | Cap2Move(abs(BOARD[ito]))
366 | Piece2Move(ipiece) );
370 pmove_last = ptree->amove;
371 pmove_last = GenCaptures(root_turn, pmove_last );
372 pmove_last = GenNoCaptures(root_turn, pmove_last );
373 pmove_last = GenCapNoProEx2(root_turn, pmove_last );
374 pmove_last = GenNoCapNoProEx2(root_turn, pmove_last );
375 pmove_last = GenDrop( root_turn, pmove_last );
376 for ( p = ptree->amove; p < pmove_last; p++ )
387 str_error = str_illegal_move;
391 && ( root_turn ? IsHandPawn(HAND_W) : IsHandPawn(HAND_B) ) )
397 u = BBToU( BB_WPAWN_ATK );
398 if ( u & (mask_file1>>ito_file) )
400 str_error = str_double_pawn;
402 else if ( BOARD[ito+nfile] == king )
404 str_error = str_mate_drppawn;
408 u = BBToU( BB_BPAWN_ATK );
409 if ( u & (mask_file1>>ito_file) ) { str_error = str_double_pawn; }
410 else if ( BOARD[ito-nfile] == -king )
412 str_error = str_mate_drppawn;
424 str_CSA_move( unsigned int move )
427 int ifrom, ito, ipiece_move, is_promote;
429 is_promote = (int)I2IsPromote(move);
430 ipiece_move = (int)I2PieceMove(move);
431 ifrom = (int)I2From(move);
432 ito = (int)I2To(move);
436 snprintf( str, 7, "%d%d%d%d%s",
437 9-aifile[ifrom], airank[ifrom]+1,
438 9-aifile[ito], airank[ito] +1,
439 astr_table_piece[ ipiece_move + promote ] );
441 else if ( ifrom < nsquare )
443 snprintf( str, 7, "%d%d%d%d%s",
444 9-aifile[ifrom], airank[ifrom]+1,
445 9-aifile[ito], airank[ito] +1,
446 astr_table_piece[ ipiece_move ] );
449 snprintf( str, 7, "00%d%d%s",
450 9-aifile[ito], airank[ito]+1,
451 astr_table_piece[ From2Drop(ifrom) ] );
459 read_board_rep1( const char *str_line, min_posi_t *pmin_posi )
463 int piece, ifile, irank, isquare;
464 signed char board[nsquare];
466 memcpy( board, &min_posi_no_handicap.asquare, nsquare );
468 for ( p = str_line + 2; p[0] != '\0'; p += 4 )
470 if ( p[1] == '\0' || p[2] == '\0' || p[3] == '\0' )
472 str_error = str_bad_board;
478 piece = str2piece( str_piece );
483 isquare = irank * nfile + ifile;
484 if ( piece == -2 || ifile < file1 || ifile > file9 || irank < rank1
485 || irank > rank9 || abs(board[isquare]) != piece )
487 str_error = str_bad_board;
490 board[isquare] = empty;
493 for ( isquare = 0; isquare < nsquare; isquare++ ) if ( board[isquare] )
495 if ( pmin_posi->asquare[isquare] )
497 str_error = str_bad_board;
500 pmin_posi->asquare[isquare] = board[isquare];
509 usi2csa( const tree_t * restrict ptree, const char *str_usi, char *str_csa )
511 int sq_file, sq_rank, sq, pc;
513 if ( '1' <= str_usi[0] && str_usi[0] <= '9'
514 && 'a' <= str_usi[1] && str_usi[1] <= 'i'
515 && '1' <= str_usi[2] && str_usi[2] <= '9'
516 && 'a' <= str_usi[3] && str_usi[3] <= 'i' )
518 str_csa[0] = str_usi[0];
519 str_csa[1] = (char)( str_usi[1] + '1' - 'a' );
520 str_csa[2] = str_usi[2];
521 str_csa[3] = (char)( str_usi[3] + '1' - 'a' );
523 sq_file = str_csa[0]-'0';
524 sq_file = 9 - sq_file;
525 sq_rank = str_csa[1]-'0';
526 sq_rank = sq_rank - 1;
527 sq = sq_rank * 9 + sq_file;
529 if ( str_usi[4] == '+' ) { pc += promote; }
531 str_csa[4] = astr_table_piece[pc][0];
532 str_csa[5] = astr_table_piece[pc][1];
538 if ( isascii( (int)str_usi[0] )
539 && isalpha( (int)str_usi[0] )
541 && '1' <= str_usi[2] && str_usi[2] <= '9'
542 && 'a' <= str_usi[3] && str_usi[3] <= 'i' )
546 str_csa[2] = str_usi[2];
547 str_csa[3] = (char)( str_usi[3] - 'a' + '1' );
549 switch ( str_usi[0] )
551 case 'P': pc = pawn; break;
552 case 'L': pc = lance; break;
553 case 'N': pc = knight; break;
554 case 'S': pc = silver; break;
555 case 'G': pc = gold; break;
556 case 'B': pc = bishop; break;
557 case 'R': pc = rook; break;
561 str_csa[4] = astr_table_piece[pc][0];
562 str_csa[5] = astr_table_piece[pc][1];
568 snprintf( str_message, SIZE_MESSAGE, "%s: %s", str_illegal_move, str_usi );
569 str_error = str_message;
575 csa2usi( const tree_t * restrict ptree, const char *str_csa, char *str_usi )
577 if ( str_csa[0] == '0' && str_csa[1] == '0'
578 && '1' <= str_csa[2] && str_csa[2] <= '9'
579 && '1' <= str_csa[3] && str_csa[3] <= '9'
580 && 'A' <= str_csa[4] && str_csa[4] <= 'Z'
581 && 'A' <= str_csa[5] && str_csa[5] <= 'Z' )
583 switch ( str2piece( str_csa + 4 ) )
585 case pawn: str_usi[0] = 'P'; break;
586 case lance: str_usi[0] = 'L'; break;
587 case knight: str_usi[0] = 'N'; break;
588 case silver: str_usi[0] = 'S'; break;
589 case gold: str_usi[0] = 'G'; break;
590 case bishop: str_usi[0] = 'B'; break;
591 case rook: str_usi[0] = 'R'; break;
592 default: return -1; break;
596 str_usi[2] = str_csa[2];
597 str_usi[3] = (char)( str_csa[3] + 'a' - '1' );
604 if ( '1' <= str_csa[0] && str_csa[0] <= '9'
605 && '1' <= str_csa[1] && str_csa[1] <= '9'
606 && '1' <= str_csa[2] && str_csa[2] <= '9'
607 && '1' <= str_csa[3] && str_csa[3] <= '9'
608 && 'A' <= str_csa[4] && str_csa[4] <= 'Z'
609 && 'A' <= str_csa[5] && str_csa[5] <= 'Z' )
611 int sq_file, sq_rank, sq, pc;
614 str_usi[0] = str_csa[0];
615 str_usi[1] = (char)( str_csa[1] + 'a' - '1' );
616 str_usi[2] = str_csa[2];
617 str_usi[3] = (char)( str_csa[3] + 'a' - '1' );
619 sq_file = str_csa[0]-'0';
620 sq_file = 9 - sq_file;
622 sq_rank = str_csa[1]-'0';
623 sq_rank = sq_rank - 1;
624 sq = sq_rank * 9 + sq_file;
627 if ( pc + promote == str2piece( str_csa + 4 ) )
632 else { str_usi[4] = '\0'; }
646 out_CSA_header( const tree_t * restrict ptree, record_t *pr )
650 fprintf( pr->pf, "'Bonanza version " BNZ_VER "\n" );
652 if ( pr->str_name1[0] != '\0' )
654 fprintf( pr->pf, "N+%s\n", pr->str_name1 );
657 if ( pr->str_name2[0] != '\0' )
659 fprintf( pr->pf, "N-%s\n", pr->str_name2 );
663 if ( t == (time_t)-1 ) { out_warning( "%s time() faild." ); }
665 #if defined(_MSC_VER)
667 localtime_s( &tm, &t );
668 fprintf( pr->pf, "$START_TIME:%4d/%02d/%02d %02d:%02d:%02d\n",
669 tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
670 tm.tm_hour, tm.tm_min, tm.tm_sec );
673 ptm = localtime( &t );
674 fprintf( pr->pf, "$START_TIME:%4d/%02d/%02d %02d:%02d:%02d\n",
675 ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,
676 ptm->tm_hour, ptm->tm_min, ptm->tm_sec );
680 if ( ! memcmp( BOARD, min_posi_no_handicap.asquare, nsquare )
681 && min_posi_no_handicap.turn_to_move == root_turn
682 && min_posi_no_handicap.hand_black == HAND_B
683 && min_posi_no_handicap.hand_white == HAND_W )
685 fprintf( pr->pf, "PI\n" );
689 out_board( ptree, pr->pf, 0, 1 );
693 if ( root_turn ) { fprintf( pr->pf, "-\n" ); }
694 else { fprintf( pr->pf, "+\n" ); }
700 in_CSA_header( tree_t * restrict ptree, record_t *pr, int flag )
703 const char *str_name1, *str_name2;
704 char str_line[ SIZE_CSALINE ];
705 int iret, is_rep1_done, is_rep2_done, is_all_done, i, j;
707 for ( i = 0; i < MAX_ANSWER; i++ ) { pr->info.str_move[i][0] = '\0'; }
708 str_name1 = str_name2 = NULL;
710 /* version and info */
713 iret = read_CSA_line( pr, str_line );
714 if ( iret < 0 ) { return iret; }
716 if ( str_line[0] != 'N'
717 && str_line[0] != 'V'
718 && str_line[0] != '$' ) { break; }
720 if ( ! memcmp( str_line, "$ANSWER:", 8 ) )
722 for ( i = 0; i < MAX_ANSWER; i++ )
724 for ( j = 0; j < 8; j++ )
726 pr->info.str_move[i][j] = str_line[8+i*8+j];
728 pr->info.str_move[i][7] = '\0';
729 if ( str_line[8+i*8+7] == '\0' ) { break; }
731 if ( i == MAX_ANSWER )
733 snprintf( str_message, SIZE_MESSAGE, str_fmt_line, pr->lines,
734 "The number of answers reached MAX_ANSWER." );
735 str_error = str_message;
739 else if ( ! memcmp( str_line, "N+", 2 ) )
741 strncpy( pr->str_name1, str_line+2, SIZE_PLAYERNAME-1 );
742 pr->str_name1[SIZE_PLAYERNAME-1] = '\0';
743 str_name1 = pr->str_name1;
745 else if ( ! memcmp( str_line, "N-", 2 ) )
747 strncpy( pr->str_name2, str_line+2, SIZE_PLAYERNAME-1 );
748 pr->str_name2[SIZE_PLAYERNAME-1] = '\0';
749 str_name2 = pr->str_name2;
754 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
755 pr->lines, str_unexpect_eof );
756 str_error = str_message;
760 /* board representation */
761 memset( &min_posi.asquare, empty, nsquare );
762 min_posi.hand_black = min_posi.hand_white = 0;
763 is_rep1_done = is_rep2_done = is_all_done = 0;
764 while ( str_line[0] == 'P' )
766 if ( str_line[1] == 'I' && ! is_rep2_done && ! is_all_done )
769 iret = read_board_rep1( str_line, &min_posi );
771 else if ( isdigit( (int)str_line[1] ) && str_line[1] != '0'
772 && ! is_rep1_done && ! is_all_done )
775 iret = read_board_rep2( str_line, &min_posi );
777 else if ( str_line[1] == '+' || str_line[1] == '-' )
779 is_all_done = iret = read_board_rep3( str_line, &min_posi );
784 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
785 pr->lines, str_error );
786 str_error = str_message;
790 iret = read_CSA_line( pr, str_line );
791 if ( iret < 0 ) { return iret; }
794 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
795 pr->lines, str_unexpect_eof );
796 str_error = str_message;
802 if ( strcmp( str_line, "+" ) && strcmp( str_line, "-" ) )
804 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
805 pr->lines, str_bad_record );
806 str_error = str_message;
809 min_posi.turn_to_move = (char)( ( str_line[0] == '+' ) ? black : white );
811 return ini_game( ptree, &min_posi, flag, str_name1, str_name2 );
816 read_board_rep3( const char *str_line, min_posi_t *pmin_posi )
818 int is_all_done, irank, ifile, isquare, piece, n, color;
819 int npawn, nlance, nknight, nsilver, ngold, nbishop, nrook;
820 unsigned int handv, hand_white, hand_black;
826 color = str_line[1] == '+' ? black : white;
827 for ( n = 2; str_line[n] != '\0'; n += 4 ) {
828 if ( str_line[n+1] == '\0' || str_line[n+2] == '\0'
829 || str_line[n+3] == '\0' || is_all_done )
831 str_error = str_bad_board;
834 if ( str_line[n] == '0' && str_line[n+1] == '0'
835 && str_line[n+2] == 'A' && str_line[n+3] == 'L' ) {
836 hand_black = pmin_posi->hand_black;
837 hand_white = pmin_posi->hand_white;
838 npawn = (int)(I2HandPawn(hand_black) + I2HandPawn(hand_white));
839 nlance = (int)(I2HandLance(hand_black) + I2HandLance(hand_white));
840 nknight = (int)(I2HandKnight(hand_black) + I2HandKnight(hand_white));
841 nsilver = (int)(I2HandSilver(hand_black) + I2HandSilver(hand_white));
842 ngold = (int)(I2HandGold(hand_black) + I2HandGold(hand_white));
843 nbishop = (int)(I2HandBishop(hand_black) + I2HandBishop(hand_white));
844 nrook = (int)(I2HandRook(hand_black) + I2HandRook(hand_white));
845 for ( isquare = 0; isquare < nsquare; isquare++ )
846 switch ( abs( pmin_posi->asquare[isquare] ) )
848 case pawn: case pro_pawn: npawn++; break;
849 case lance: case pro_lance: nlance++; break;
850 case knight: case pro_knight: nknight++; break;
851 case silver: case pro_silver: nsilver++; break;
852 case gold: ngold++; break;
853 case bishop: case horse: nbishop++; break;
854 case rook: case dragon: nrook++; break;
856 assert( pmin_posi->asquare[isquare] == empty );
859 handv = flag_hand_pawn * ( npawn_max -npawn );
860 handv += flag_hand_lance * ( nlance_max -nlance );
861 handv += flag_hand_knight * ( nknight_max -nknight );
862 handv += flag_hand_silver * ( nsilver_max -nsilver );
863 handv += flag_hand_gold * ( ngold_max -ngold );
864 handv += flag_hand_bishop * ( nbishop_max -nbishop );
865 handv += flag_hand_rook * ( nrook_max -nrook );
866 if ( color ) { pmin_posi->hand_white += handv; }
867 else { pmin_posi->hand_black += handv; }
872 ifile = str_line[n+0]-'0';
873 irank = str_line[n+1]-'0';
874 str_piece[0] = str_line[n+2];
875 str_piece[1] = str_line[n+3];
876 piece = str2piece( str_piece );
879 if ( ifile == 0 && ifile == 0 )
883 case pawn: handv = flag_hand_pawn; break;
884 case lance: handv = flag_hand_lance; break;
885 case knight: handv = flag_hand_knight; break;
886 case silver: handv = flag_hand_silver; break;
887 case gold: handv = flag_hand_gold; break;
888 case bishop: handv = flag_hand_bishop; break;
889 case rook: handv = flag_hand_rook; break;
891 str_error = str_bad_board;
894 if ( color ) { pmin_posi->hand_white += handv; }
895 else { pmin_posi->hand_black += handv; }
901 isquare = irank * nfile + ifile;
902 if ( piece == -2 || ifile < file1 || ifile > file9
903 || irank < rank1 || irank > rank9 || pmin_posi->asquare[isquare] )
905 str_error = str_bad_board;
908 pmin_posi->asquare[isquare] = (signed char)( color ? -piece : piece );
917 read_board_rep2( const char * str_line, min_posi_t *pmin_posi )
919 int irank, ifile, piece;
924 irank = str_line[1] - '1';
926 for ( ifile = 0; ifile < nfile; ifile++ )
927 if ( str_line[2+ifile*3] == '+' || str_line[2+ifile*3] == '-' )
929 str_piece[0] = str_line[2+ifile*3+1];
930 str_piece[1] = str_line[2+ifile*3+2];
931 piece = str2piece( str_piece );
932 if ( piece < 0 || pmin_posi->asquare[ irank*nfile + ifile ] )
934 str_error = str_bad_board;
937 pmin_posi->asquare[ irank*nfile + ifile ]
938 = (signed char)( str_line[ 2 + ifile*3 ] == '-' ? -piece : piece );
940 else { pmin_posi->asquare[ irank*nfile + ifile ] = empty; }
947 str2piece( const char *str )
951 for ( i = 0; i < 16; i++ )
953 if ( ! strcmp( astr_table_piece[i], str ) ) { break; }
955 if ( i == 0 || i == piece_null || i == 16 ) { i = -2; }
961 /* reads a csa line in str, trancates trailing spases.
963 * 0 EOF, no line is read.
964 * 1 a csa line is read in str
968 read_CSA_line( record_t *pr, char *str )
974 c = skip_comment( pr );
975 if ( isgraph( c ) || c == EOF ) { break; }
977 if ( c == EOF ) { return 0; }
979 do_comma = ( c == 'N' || c == '$' ) ? 0 : 1;
981 for ( i = 0; i < SIZE_CSALINE-1; i++ )
983 if ( c == EOF || c == '\n' || ( do_comma && c == ',' ) ) { break; }
988 if ( i == SIZE_CSALINE-1 )
990 snprintf( str_message, SIZE_MESSAGE, str_fmt_line,
991 pr->lines, str_ovrflw_line );
996 while ( isascii( (int)str[i] ) && isspace( (int)str[i] ) ) { i--; }
1004 skip_comment( record_t *pr )
1008 c = read_char( pr );
1011 if ( c != '\'' ) { break; }
1014 c = read_char( pr );
1015 if ( c == EOF || c == '\n' ) { break; }
1024 read_char( record_t *pr )
1028 c = fgetc( pr->pf );
1029 if ( c == '\n' ) { pr->lines++; }