The readfile filter takes a single argument, a filename. Its value is the contents of the file named by filename as a string:
    X=readfile "example.cqo"

The filename must have extension .pgn, .cqo or .cql.

If the filter filename fails to match, is not of the proper format, or if a read error occurs, CQL halts. Otherwise, the readfile filter always matches.

Any use of readfile forces CQL to run single-threaded

Use of readfile

readfile is typically used either with a dictionary or with a persistent string in the first game, in the first position.

For example, suppose the file fens.cqo contains a list of FEN values and game numbers separated by commas, one per line (like the one in the example in the writefile documentation). We can read this file into a dictionary, then, for each position in the current database whose fen matches a fen in the dictionary, comment that the position was seen, and the gamenumber in the fens.cqo file it matched

    cql(input hhdbvi.pgn)
    if (initial and gamenumber==1){
      Fens=readfile "fens.cqo"
      while (Fens ~~ ([^,]+),(\d+))
        dictionary FensDictionary[\1]=\2
    }//end if (initial and gamenumber)...

if (OldNumber = FensToDictionary[fen]) comment ("current position marked for gamenumber" OldNumber)

Notes on using readfile

If a readfile filter occurs in the code, remember that the filter by default will be evaluated in each position, in each game, like any other CQL filter. As in the example above, usually you will only want to read the file at the start of game 1 of the database.

If you are using a persistent string to store the contents of a file, make sure it is a quiet persistent string. Otherwise, its value will be printed after CQL is finished:

    if (gamenumber==1 and initial)
     persistent quiet FileContents = readfile(filename.cqo)