예제 #1
0
파일: pbook.cpp 프로젝트: ageneau/scid
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// PBook::StripOpcode:
//    Strips the specified opcode from every position in the book.
//    Only the first occurrence of an opcode is removed for any position,
//    but opcodes are not supposed to occur more than once anyway.
//    Returns the number of positions where an opcode was removed.
uint
PBook::StripOpcode (const char * opcode)
{
    char * searchCode = new char [strLength(opcode) + 2];
    strCopy (searchCode, opcode);
    strAppend (searchCode, " ");
    DString dstr;
    uint countFound = 0;

    for (uint i=0; i < NodeListCount; i++) {
        bookNodeT * node = NodeList[i];
        if (node == NULL) { continue; }
        const char * s = node->data.comment;
        int startIndex = -1;
        int index = 0;
        // Look for a line with a matching opcode:
        while (*s != 0) {
            while (*s == '\n'  ||  *s == ' ') { s++; index++; }
            if (strIsPrefix (searchCode, s)) {
                startIndex = index;
                countFound++;
                break;
            }
            while (*s != 0  &&  *s != '\n') { s++; index++; }
        }
        if (startIndex > -1) {
            s = node->data.comment;
            index = 0;
            // Add all characters before the line to be stripped:
            dstr.Clear();
            while (index < startIndex) {
                dstr.AddChar (s[index]);
                index++;
            }
            // Now find the end of this line:
            s = &(s[startIndex + 1]);
            while (*s != 0  &&  *s != '\n') { s++; }
            if (*s == '\n') { s++; }
            while (*s != 0) { dstr.AddChar (*s);  s++; }

            delete[] node->data.comment;
            node->data.comment = strDuplicate (dstr.Data());
        }
    }
    delete[] searchCode;
    return countFound;
}
예제 #2
0
파일: pbook.cpp 프로젝트: ageneau/scid
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// PBook::ReadFile(): read in a file.
errorT
PBook::ReadFile ()
{
    ASSERT (FileName != NULL);

    ReadOnly = false;
    MFile fp;
    if (fp.Open (FileName, FMODE_Both) != OK) {
        ReadOnly = true;
        if (fp.Open (FileName, FMODE_ReadOnly) != OK) {
            return ERROR_FileOpen;
        }
    }

    LineCount = 1;
    Position * pos = new Position;
    DString * line = new DString;
    ReadLine(line, &fp);
    DString dstr;
    
    while (line->Length() || ! fp.EndOfFile()) {

        if (pos->ReadFromFEN (line->Data()) != OK) {
            fprintf (stderr, "Error reading line: %u\n", LineCount);
            LineCount++;
            line->Clear();
            ReadLine(line, &fp);
            continue;
            //exit (1);
        }

        char * s = (char *) line->Data();
        // Skip over first four fields, which were the position:
        while (*s == ' ') { s++; }
        for (uint i=0; i < 4; i++) {
            while (*s != ' '  &&  *s != 0) { s++; }
            while (*s == ' ') { s++; }
        }
        // Now process each field in turn:
        while (*s == ';'  ||  *s == ' ') { s++; }
        dstr.Clear();
        while (*s != 0) {
            while (*s == ';'  ||  *s == ' ') { s++; }
            bool seenCode = false;
            while (*s != ';'  &&  *s != 0) {
                seenCode = true;
                char ch = *s;
                // Check for backslash (escape) character:
                if (ch == '\\') {
                    s++;
                    ch = *s;
                    // "\s" -> semicolon within a field:
                    if (ch == 's') { ch = ';'; }
                }
                dstr.AddChar (ch);
                s++;
            }
            if (seenCode) { dstr.AddChar ('\n'); }
        }

        if (Insert (pos, dstr.Data()) != OK) {
            //fprintf (stderr, "Warning: position already exists! Line %u\n",
            //         LineCount);
        }
        LineCount++;
        line->Clear();
        ReadLine(line, &fp);
    }
    delete pos;
    delete line;
    Altered = false;
    NextIndex = NodeListCount - 1;
    return OK;
}
예제 #3
0
파일: pbook.cpp 프로젝트: ageneau/scid
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// PBook::ReadEcoFile():
//    Read an ECO (not EPD) format file.
errorT
PBook::ReadEcoFile ()
{
    MFile fp;
    if (fp.Open (FileName, FMODE_ReadOnly) != OK) {
        return ERROR_FileOpen;
    }

    ReadOnly = true;
    LineCount = 1;
    Position std_start;
    std_start.StdStart();
    DString text;
    DString moves;
    ecoStringT ecoStr;
    ecoT ecoCode;
    int ch;
    errorT err = OK;
    bool done = false;

    // Loop to read in and add all positions:

    while (!done) {
        // Find the next ECO code:
        while (true) {
            ch = fp.ReadOneByte();
            if (ch == EOF) { done = true; break; }
            if (ch == '\n') { LineCount++; }
            if (ch >= 'A'  &&  ch <= 'E') { break; }
            if (ch == '#') {
                while (ch != '\n'  &&  ch != EOF) {
                    ch = fp.ReadOneByte();
                }
                if (ch == EOF) { done = true; }
                LineCount++;
            }
        }
        if (done) { break; }

        // Read in the rest of the ECO code:
        ecoStr[0] = ch;
        ch = fp.ReadOneByte();
        if (ch < '0'  ||  ch > '9') { goto corrupt; }
        ecoStr[1] = ch;
        ch = fp.ReadOneByte();
        if (ch < '0'  ||  ch > '9') { goto corrupt; }
        ecoStr[2] = ch;
        ecoStr[3] = 0;

        // Now check for optional extra part of code, e.g. "A00a1":
        ch = fp.ReadOneByte();
        if (ch >= 'a'  &&  ch <= 'z') {
            ecoStr[3] = ch; ecoStr[4] = 0;
            ch = fp.ReadOneByte();
            if (ch >= '1'  &&  ch <= '4') {
                ecoStr[4] = ch; ecoStr[5] = 0;
            }
        }

        // Now put ecoCode in the text string and read the text in quotes:
        ecoCode = eco_FromString (ecoStr);
        eco_ToExtendedString (ecoCode, ecoStr);
        text.Clear();
        text.Append ("eco ", ecoStr, " [");

        // Find the start of the text:
        while ((ch = fp.ReadOneByte()) != '"') {
            if (ch == EOF) { goto corrupt; }
        }
        while ((ch = fp.ReadOneByte()) != '"') {
            if (ch == EOF) { goto corrupt; }
            text.AddChar ((char) ch);
        }
        text.Append ("]\n");

        // Now read the position:
        moves.Clear();
        char prev = 0;
        while ((ch = fp.ReadOneByte()) != '*') {
            if (ch == EOF) { goto corrupt; }
            if (ch == '\n') {
                ch = ' ';
                LineCount++;
            }
            if (ch != ' '  ||  prev != ' ') {
                moves.AddChar ((char) ch);
            }
            prev = ch;
        }
        Position pos (std_start);
        err = pos.ReadLine (moves.Data());
        if (err != OK) { goto corrupt; }
        text.Append ("moves ", strTrimLeft (moves.Data()), "\n");
        if (Insert (&pos, text.Data()) != OK) {
            // Position already exists: just ignore it.
        }
    }
    return OK;
corrupt:
    return ERROR_Corrupt;
}