2 * Program: pgn-extract: a Portable Game Notation (PGN) extractor.
3 * Copyright (C) 1994-2014 David Barnes
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 1, or (at your option)
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * David Barnes may be contacted as D.J.Barnes@kent.ac.uk
19 * http://www.cs.kent.ac.uk/people/staff/djb/
38 static FILE *yyin = NULL;
40 /* Read the list of extraction criteria from TagFile.
41 * This doesn't use the normal lexical analyser before the
42 * PGN files are processed but circumvents next_token by
43 * calling get_tag() and get_string. This allows it to detect
44 * EOF before yywrap() is called.
45 * Be careful to leave lex in the right state.
48 read_tag_file(const char *TagFile)
50 yyin = fopen(TagFile,"r");
52 Boolean keep_reading = TRUE;
55 char *line = next_input_line(yyin);
57 keep_reading = process_tag_line(TagFile,line);
64 /* Call yywrap in order to set up for the next (first) input file. */
69 fprintf(GlobalState.logfile,
70 "Unable to open %s for reading.\n",TagFile);
75 /* Read the contents of a file that lists the
76 * required output ordering for tags.
79 read_tag_roster_file(const char *RosterFile)
80 { Boolean keep_reading = TRUE;
81 yyin = must_open_file(RosterFile,"r");
84 char *line = next_input_line(yyin);
86 keep_reading = process_roster_line(line);
93 /* Call yywrap in order to set up for the next (first) input file. */
97 /* Extract a tag/value pair from the given line.
98 * Return TRUE if this was successful.
101 process_tag_line(const char *TagFile,char *line)
103 Boolean keep_reading = TRUE;
104 if(non_blank_line(line)){
105 unsigned char *linep = (unsigned char *) line;
106 /* We should find a tag. */
107 LinePair resulting_line = gather_tag(line,linep);
110 /* Pick up where we are now. */
111 line = resulting_line.line;
112 linep = resulting_line.linep;
113 tag_token = resulting_line.token;
114 if(tag_token != NO_TOKEN){
115 /* Pick up which tag it was. */
116 int tag_index = yylval.tag_index;
117 /* Allow for an optional operator. */
118 TagOperator operator = NONE;
120 /* Skip whitespace up to a double quote. */
121 while(is_character_class(*linep, WHITESPACE)){
124 /* Allow for an optional operator. */
125 if(is_character_class(*linep, OPERATOR)){
131 operator = LESS_THAN_OR_EQUAL_TO;
133 else if(*linep == '>'){
135 operator = NOT_EQUAL_TO;
138 operator = LESS_THAN;;
145 operator = GREATER_THAN_OR_EQUAL_TO;
148 operator = GREATER_THAN;
156 fprintf(GlobalState.logfile,
157 "Internal error: unknown operator in %s\n",line);
161 /* Skip whitespace up to a double quote. */
162 while(is_character_class(*linep, WHITESPACE)){
167 if(is_character_class(*linep, DOUBLE_QUOTE)){
168 /* A string, as expected. */
170 resulting_line = gather_string(line,linep);
171 line = resulting_line.line;
172 linep = resulting_line.linep;
173 if(tag_token == TAG){
174 /* Treat FEN* tags as a special case.
175 * Use the position they represent to indicate
176 * a positional match.
178 if(tag_index == FEN_TAG){
179 add_fen_positional_match(yylval.token_string);
180 (void) free((void *)yylval.token_string);
182 else if(tag_index == PSEUDO_FEN_PATTERN_TAG){
183 add_fen_pattern_match(yylval.token_string);
184 (void) free((void *)yylval.token_string);
187 add_tag_to_list(tag_index,yylval.token_string,operator);
188 (void) free((void *)yylval.token_string);
192 if(!GlobalState.skipping_current_game){
193 fprintf(GlobalState.logfile,
194 "File %s: unrecognised tag name %s\n",
197 (void) free((void *)yylval.token_string);
201 if(!GlobalState.skipping_current_game){
202 fprintf(GlobalState.logfile,
203 "File %s: missing quoted tag string in %s at %s\n",
209 /* Terminate the reading, as we have run out of tags. */
210 keep_reading = FALSE;
216 /* Extract a tag name from the given line.
217 * Return TRUE if this was successful.
220 process_roster_line(char *line)
222 Boolean keep_reading = TRUE;
223 if(non_blank_line(line)){
224 unsigned char *linep = (unsigned char *) line;
225 /* We should find a tag. */
226 LinePair resulting_line = gather_tag(line,linep);
229 /* Pick up where we are now. */
230 line = resulting_line.line;
231 linep = resulting_line.linep;
232 tag_token = resulting_line.token;
233 if(tag_token != NO_TOKEN){
234 /* Pick up which tag it was. */
235 int tag_index = yylval.tag_index;
236 add_to_output_tag_order((TagName) tag_index);
239 /* Terminate the reading, as we have run out of tags. */
240 keep_reading = FALSE;