]> git.sesse.net Git - pgn-extract/commitdiff
Support scanning only a range of the file.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 12 Dec 2014 23:57:41 +0000 (00:57 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 12 Dec 2014 23:57:43 +0000 (00:57 +0100)
argsfile.c
grammar.c
lex.c
lex.h
main.c
typedef.h

index e2caa076645d738b20e8c7158f29d051e7822dd3..7bba9011b6da589af20e3c20285ce8c53646486f 100644 (file)
@@ -1078,6 +1078,14 @@ process_long_form_argument(const char *argument, const char *associated_value)
         GlobalState.output_total_plycount = TRUE;
         return 1;
     }
         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);
     else if(stringcompare(argument, "version") == 0) {
         fprintf(GlobalState.logfile, "pgn-extract %s\n", CURRENT_VERSION);
        exit(0);
index ab2278381a8c3250bd0c64a4143d134aa4128ff6..133947ec0ef2a8670d412458dd3fe85f5dcdb31e 100644 (file)
--- a/grammar.c
+++ b/grammar.c
@@ -83,7 +83,7 @@ static void check_result(char **Tags,const char *terminating_result);
 static void free_comment_list(CommentList *comment_list);
 static void DealWithEcoLine(Move *move_list);
 static void DealWithGame(Move *move_list);
 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.
 
     /* Initialise the game header structure to contain
      * space for the default number of tags.
@@ -236,17 +236,18 @@ select_output_file(StateInfo *GameState,const char *eco)
    * Conditions for finishing processing, other than all the input
    * having been processed.
    */
    * 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;
 
 }
 
 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);
         }
         if(file_type == NORMALFILE){
             DealWithGame(move_list);
         }
@@ -997,6 +998,11 @@ DealWithEcoLine(Move *move_list)
 int
 yyparse(SourceFileType file_type)
 {
 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);
     setup_for_new_game();
     current_symbol = skip_to_next_game(NO_TOKEN);
     ParseOptGameList(file_type);
@@ -1004,7 +1010,7 @@ yyparse(SourceFileType file_type)
         /* Ok -- EOF. */
         return 0;
     }
         /* Ok -- EOF. */
         return 0;
     }
-    else if(finished_processing()) {
+    else if(finished_processing(file_type)) {
         /* Ok -- done all we need to. */
        return 0;
     }
         /* Ok -- done all we need to. */
        return 0;
     }
diff --git a/lex.c b/lex.c
index 0c8d26f192148e54c1ea5ac32f54587dc29dbfbc..23d61316d428c39c54d4b88e9fcb73c54b2b277d 100644 (file)
--- a/lex.c
+++ b/lex.c
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 #include <ctype.h>
 #if defined(__BORLANDC__) || defined(_MSC_VER)
 #include <io.h>
 #include <ctype.h>
 #if defined(__BORLANDC__) || defined(_MSC_VER)
 #include <io.h>
@@ -1101,6 +1102,37 @@ open_input(const char *infile)
     return yyin != NULL;
 }
 
     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)
         /* Simple interface to open_input for the ECO file. */
 Boolean
 open_eco_file(const char *eco_file)
diff --git a/lex.h b/lex.h
index e0cb4dc40062471dba964fb98a6f12ac27717695..a310e9dba94128c55667a39bea5de72d1a4a396c 100644 (file)
--- a/lex.h
+++ b/lex.h
@@ -78,6 +78,8 @@ const char *tag_header_string(TagName tag);
 Boolean open_first_file(void);
 const char *input_file_name(unsigned file_number);
 unsigned current_file_number(void);
 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);
 Boolean open_eco_file(const char *eco_file);
 int yywrap(void);
 void add_filename_to_source_list(const char *filename,SourceFileType file_type);
diff --git a/main.c b/main.c
index 218793a0f7005bf5d352faa0ed85c7d80b4fb058..ec4df57cdf0e356223ab6ab49746762a21d87fc9 100644 (file)
--- a/main.c
+++ b/main.c
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <limits.h>
 #include "bool.h"
 #include "mymalloc.h"
 #include "defs.h"
 #include "bool.h"
 #include "mymalloc.h"
 #include "defs.h"
@@ -106,6 +107,8 @@ StateInfo GlobalState = {
     "MATCH",             /* position_match_comment (--markpositionmatches) */
     (char *)NULL,         /* current_input_file */
     NORMALFILE,           /* current_file_type */
     "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) */
     DEFAULT_ECO_FILE,     /* eco_file (-e) */
     (FILE *)NULL,         /* outputfile (-o, -a). Default is stdout */
     (char *)NULL,         /* output_filename (-o, -a) */
index 65c93b59a1aa26934d4c536005b507f6ff9a7653..cf7be10005b34e242eee55463a6c315d63af1aae 100644 (file)
--- a/typedef.h
+++ b/typedef.h
@@ -279,6 +279,12 @@ typedef struct {
     const char *current_input_file;
     /* Whether this is a CHECKFILE or a NORMALFILE. */
     SourceFileType current_file_type;
     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. */
     /* File of ECO lines. */
     const char *eco_file;
     /* Where to write the extracted games. */