void MangoGross::parseQuery (Scanner &scanner) { scanner.skipSpace(); char c = scanner.readChar(); if (c == '>') { if (scanner.readChar() != '=') throw Error("expecting '=' after '>'"); _sign = 1; } else if (c == '<') { if (scanner.readChar() != '=') throw Error("expecting '=' after '<'"); _sign = -1; } else if (c == '=') _sign = 0; else throw Error("expected one of '<= >= =', got %c", c); MoleculeGrossFormula::fromString(scanner, _query_gross); ArrayOutput out(_conditions); bool first = true; if (_sign == 0) { QS_DEF(Array<char>, query_gross_str); MoleculeGrossFormula::toString(_query_gross, query_gross_str); out.printf("gross = '%s'", query_gross_str.ptr()); } else for (int i = 0; i < NELEM(MangoIndex::counted_elements); i++) { int elem = MangoIndex::counted_elements[i]; if (_query_gross[elem] <= 0 && _sign == 1) continue; if (!first) out.printf(" AND "); first = false; if (_sign == 1) out.printf("cnt_%s >= %d", Element::toString(elem), _query_gross[elem]); else // _sign == -1 out.printf("cnt_%s <= %d", Element::toString(elem), _query_gross[elem]); } out.writeChar(0); }
int Element::read (Scanner &scanner) { char str[3] = {0, 0, 0}; str[0] = scanner.readChar(); if (islower(scanner.lookNext())) str[1] = scanner.readChar(); return fromString(str); }
bool MoleculeAutoLoader::tryMDLCT (Scanner &scanner, Array<char> &outbuf) { int pos = scanner.tell(); bool endmark = false; QS_DEF(Array<char>, curline); outbuf.clear(); while (!scanner.isEOF()) { int len = scanner.readByte(); if (len > 90) // Molfiles and Rxnfiles actually have 80 characters limit { scanner.seek(pos, SEEK_SET); // Garbage after endmark means end of data. // (See the note below about endmarks) if (endmark) return true; return false; } curline.clear(); while (len-- > 0) { if (scanner.isEOF()) { scanner.seek(pos, SEEK_SET); return false; } int c = scanner.readChar(); curline.push(c); } curline.push(0); if (endmark) { // We can not properly read the data to the end as there // is often garbage after the actual MDLCT data. // Instead, we are doing this lousy check: // "M END" or "$END MOL" can be followed only // by "$END CTAB" (in Markush queries), or // by "$MOL" (in Rxnfiles). Otherwise, this // is actually the end of data. if (strcmp(curline.ptr(), "$END CTAB") != 0 && strcmp(curline.ptr(), "$MOL") != 0) { scanner.seek(pos, SEEK_SET); return true; } } if (strcmp(curline.ptr(), "M END") == 0) endmark = true; else if (strcmp(curline.ptr(), "$END MOL") == 0) endmark = true; else endmark = false; outbuf.appendString(curline.ptr(), false); outbuf.push('\n'); } scanner.seek(pos, SEEK_SET); // It happened once that a valid Molfile had successfully // made its way through the above while() cycle, and thus // falsely recognized as MDLCT. To fight this case, we include // here a check that the last line was actually an endmark return endmark; }