コード例 #1
0
	bool readfields(void* object, const bsreq* fields) {
		while(*p && !islinefeed()) {
			const bsreq* req = 0;
			if(readidentifier())
				req = fields->find(buffer);
			if(!req)
				warning(ErrorNotFoundMember1pInBase2p, buffer, getbasename(fields));
			readreq(object, req, 0);
		}
		return true;
	}
コード例 #2
0
ファイル: CifFile.cpp プロジェクト: dprada/pymol-open-source
// Return true if "c" is line feed or carriage return or null
static bool islinefeed0(char c) {
  return (!c || islinefeed(c));
}
コード例 #3
0
ファイル: CifFile.cpp プロジェクト: dprada/pymol-open-source
// parse CIF contents
bool cif_file::parse() {
  char *p = contents;
  char quote;
  char prev = '\0';

  std::vector<bool> keypossible;

  // tokenize
  while (true) {
    while (iswhitespace(*p))
      prev = *(p++);

    if (!*p)
      break;

    if (*p == '#') {
      while (!(islinefeed0(*++p)));
      prev = *p;
    } else if (isquote(*p)) { // will NULL the closing quote
      quote = *p;
      keypossible.push_back(false);
      tokens.push_back(p + 1);
      while (*++p && !(*p == quote && iswhitespace0(p[1])));
      if (*p)
        *(p++) = 0;
      prev = *p;
    } else if (*p == ';' && islinefeed(prev)) { // will NULL the line feed before the closing semicolon
      keypossible.push_back(false);
      tokens.push_back(p + 1);
      while (*++p && !(islinefeed(*p) && p[1] == ';'));
      if (*p) {
        *p = 0;
        p += 2;
      }
      prev = ';';
    } else { // will null the whitespace
      char * q = p++;
      while (!iswhitespace0(*p)) ++p;
      prev = *p;
      if (p - q == 1 && (*q == '?' || *q == '.')) {
        // store values '.' (inapplicable) and '?' (unknown) as null-pointers
        q = nullptr;
        keypossible.push_back(false);
      } else {
        if (*p)
          *(p++) = 0;
        keypossible.push_back(true);
      }
      tokens.push_back(q);
    }
  }

  cif_data *current_data = nullptr, *current_frame = nullptr, *global_block = nullptr;

  // parse into dictionary
  for (unsigned int i = 0, n = tokens.size(); i < n; i++) {
    if (!keypossible[i]) {
      std::cout << "ERROR" << std::endl;
      break;
    } else if (tokens[i][0] == '_') {
      if (i + 1 == n) {
        std::cout << "ERROR truncated" << std::endl;
        break;
      }

      if (current_frame) {
        tolowerinplace(tokens[i]);
        current_frame->dict[tokens[i]].set_value(tokens[i + 1]);
      }

      i++;
    } else if (strcasecmp("loop_", tokens[i]) == 0) {
      int ncols = 0;
      int nrows = 0;
      cif_loop *loop = nullptr;

      // loop data
      if (current_frame) {
        loop = new cif_loop;

        // add to loops list
        current_frame->loops.push_back(loop);
      }

      // columns
      while (++i < n && keypossible[i] && tokens[i][0] == '_') {
        tolowerinplace(tokens[i]);

        if (current_frame) {
          current_frame->dict[tokens[i]].set_loop(loop, ncols);
        }

        ncols++;
      }

      if (loop) {
        // loop data
        loop->values = (const char **) &tokens[i];
        loop->ncols = ncols;
      }

      // rows
      while (i < n && !(keypossible[i] && isspecial(tokens[i]))) {
        i += ncols;

        if (i > n) {
          std::cout << "ERROR truncated loop" << std::endl;
          break;
        }

        nrows++;
      }

      // loop data
      if (loop) {
        loop->nrows = nrows;
      }

      i--;

    } else if (strncasecmp("data_", tokens[i], 5) == 0) {
      const char * key(tokens[i] + 5);
      datablocks[key] = current_data = current_frame = new cif_data;

    } else if (strncasecmp("global_", tokens[i], 5) == 0) {
      // STAR feature, not supported in CIF
      global_block = current_data = current_frame = new cif_data;

    } else if (strncasecmp("save_", tokens[i], 5) == 0) {
      if (tokens[i][5] && current_data) {
        // begin
        const char * key(tokens[i] + 5);
        current_data->saveframes[key] = current_frame = new cif_data;
      } else {
        // end
        current_frame = current_data;
      }
    } else {
      std::cout << "ERROR" << std::endl;
      break;
    }
  }

  if (global_block)
    delete global_block;

  return true;
}