GlobalState.output_total_plycount = TRUE;
return 1;
}
+ else if(stringcompare(argument, "startpos") == 0) {
+ GlobalState.start_position = atol(associated_value);
+ return 2;
+ }
+ else if(stringcompare(argument, "endpos") == 0) {
+ GlobalState.end_position = atol(associated_value);
+ return 2;
+ }
else if(stringcompare(argument, "version") == 0) {
fprintf(GlobalState.logfile, "pgn-extract %s\n", CURRENT_VERSION);
exit(0);
static void free_comment_list(CommentList *comment_list);
static void DealWithEcoLine(Move *move_list);
static void DealWithGame(Move *move_list);
-static Boolean finished_processing(void);
+static Boolean finished_processing(SourceFileType file_type);
/* Initialise the game header structure to contain
* space for the default number of tags.
* Conditions for finishing processing, other than all the input
* having been processed.
*/
-static Boolean finished_processing(void)
+static Boolean finished_processing(SourceFileType file_type)
{
- return (GlobalState.matching_game_number > 0 &&
- GlobalState.num_games_matched == GlobalState.matching_game_number);
+ return ((file_type != ECOFILE && at_end_of_input()) ||
+ (GlobalState.matching_game_number > 0 &&
+ GlobalState.num_games_matched == GlobalState.matching_game_number));
}
static void
ParseOptGameList(SourceFileType file_type)
{ Move *move_list = NULL;
- while(ParseGame(&move_list) && !finished_processing()){
+ while(ParseGame(&move_list) && !finished_processing(file_type)){
if(file_type == NORMALFILE){
DealWithGame(move_list);
}
int
yyparse(SourceFileType file_type)
{
+ if(file_type != ECOFILE) {
+ if(!seek_to_begin()) {
+ return 1;
+ }
+ }
setup_for_new_game();
current_symbol = skip_to_next_game(NO_TOKEN);
ParseOptGameList(file_type);
/* Ok -- EOF. */
return 0;
}
- else if(finished_processing()) {
+ else if(finished_processing(file_type)) {
/* Ok -- done all we need to. */
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include <ctype.h>
#if defined(__BORLANDC__) || defined(_MSC_VER)
#include <io.h>
return yyin != NULL;
}
+Boolean
+seek_to_begin(void)
+{
+ if(GlobalState.start_position <= 0) {
+ return TRUE;
+ }
+ if(fseek(yyin, GlobalState.start_position, SEEK_SET) != 0) {
+ fprintf(GlobalState.logfile,"Cannot seek to position %ld in %s\n",
+ GlobalState.start_position,
+ GlobalState.current_input_file);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+Boolean
+at_end_of_input(void)
+{
+ long pos;
+ if(GlobalState.end_position >= LONG_MAX) {
+ return FALSE;
+ }
+ pos = ftell(yyin);
+ if(pos == -1) {
+ fprintf(GlobalState.logfile,"Cannot find position in %s\n",
+ GlobalState.current_input_file);
+ return TRUE;
+ }
+ return pos >= GlobalState.end_position;
+}
+
/* Simple interface to open_input for the ECO file. */
Boolean
open_eco_file(const char *eco_file)
Boolean open_first_file(void);
const char *input_file_name(unsigned file_number);
unsigned current_file_number(void);
+Boolean seek_to_begin(void);
+Boolean at_end_of_input(void);
Boolean open_eco_file(const char *eco_file);
int yywrap(void);
void add_filename_to_source_list(const char *filename,SourceFileType file_type);
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <limits.h>
#include "bool.h"
#include "mymalloc.h"
#include "defs.h"
"MATCH", /* position_match_comment (--markpositionmatches) */
(char *)NULL, /* current_input_file */
NORMALFILE, /* current_file_type */
+ 0, /* start_position */
+ LONG_MAX, /* end_position */
DEFAULT_ECO_FILE, /* eco_file (-e) */
(FILE *)NULL, /* outputfile (-o, -a). Default is stdout */
(char *)NULL, /* output_filename (-o, -a) */
const char *current_input_file;
/* Whether this is a CHECKFILE or a NORMALFILE. */
SourceFileType current_file_type;
+ /* Byte positions to scan to and from in the PGN file.
+ * Starting in the middle of a game will yield unexpected
+ * results.
+ */
+ long start_position;
+ long end_position;
/* File of ECO lines. */
const char *eco_file;
/* Where to write the extracted games. */