CifFile.cpp (pymol-open-source-2.2.0) | : | CifFile.cpp (pymol-open-source-2.3.0) | ||
---|---|---|---|---|
skipping to change at line 91 | skipping to change at line 91 | |||
static void tolowerinplace(char *p) { | static void tolowerinplace(char *p) { | |||
for (; *p; p++) { | for (; *p; p++) { | |||
if (*p <= 'Z' && *p >= 'A') | if (*p <= 'Z' && *p >= 'A') | |||
*p -= 'Z' - 'z'; | *p -= 'Z' - 'z'; | |||
} | } | |||
} | } | |||
// CIF stuff | // CIF stuff | |||
static const char * EMPTY_STRING = ""; | static const char * EMPTY_STRING = ""; | |||
static cif_array EMPTY_ARRAY(NULL); | static cif_array EMPTY_ARRAY(nullptr); | |||
/* | /* | |||
* Class to store CIF loops. Only for parsing, do not use in any higher level | * Class to store CIF loops. Only for parsing, do not use in any higher level | |||
* reading functions. | * reading functions. | |||
*/ | */ | |||
class cif_loop { | class cif_loop { | |||
public: | public: | |||
int ncols; | int ncols; | |||
int nrows; | int nrows; | |||
const char **values; | const char **values; | |||
// methods | // methods | |||
const char * get_value_raw(int row, int col) const; | const char * get_value_raw(int row, int col) const; | |||
}; | }; | |||
// get table value, return NULL if indices out of bounds | // get table value, return NULL if indices out of bounds | |||
const char * cif_loop::get_value_raw(int row, int col) const { | const char * cif_loop::get_value_raw(int row, int col) const { | |||
if (row >= nrows) | if (row >= nrows) | |||
return NULL; | return nullptr; | |||
return values[row * ncols + col]; | return values[row * ncols + col]; | |||
} | } | |||
// get the number of elements in this array | // get the number of elements in this array | |||
int cif_array::get_nrows() const { | int cif_array::get_nrows() const { | |||
return (col < 0) ? 1 : pointer.loop->nrows; | return (col < 0) ? 1 : pointer.loop->nrows; | |||
} | } | |||
// get array value, return NULL if row-index out of bounds | // get array value, return NULL if row-index out of bounds | |||
// or value in ['.', '?'] | // or value in ['.', '?'] | |||
const char * cif_array::get_value(int row) const { | const char * cif_array::get_value(int row) const { | |||
if (col < 0) | if (col < 0) | |||
return (row > 0) ? NULL : pointer.value; | return (row > 0) ? nullptr : pointer.value; | |||
return pointer.loop->get_value_raw(row, col); | return pointer.loop->get_value_raw(row, col); | |||
} | } | |||
// get array value, return an empty string if missing | // get array value, return an empty string if missing | |||
const char * cif_array::as_s(int row) const { | const char * cif_array::as_s(int row) const { | |||
const char * s = get_value(row); | const char * s = get_value(row); | |||
return s ? s : EMPTY_STRING; | return s ? s : EMPTY_STRING; | |||
} | } | |||
// get array value as integer, return d (default 0) if missing | // get array value as integer, return d (default 0) if missing | |||
skipping to change at line 174 | skipping to change at line 174 | |||
/* | /* | |||
* Get a pointer to array or NULL if not found | * Get a pointer to array or NULL if not found | |||
* | * | |||
* Can lookup up to 3 different aliases, the first one found is returned. | * Can lookup up to 3 different aliases, the first one found is returned. | |||
* Also supports an alias shortcut for the trivial case where mmCIF uses | * Also supports an alias shortcut for the trivial case where mmCIF uses | |||
* a colon and CIF uses an underscore: (key="_foo?bar") is identical to | * a colon and CIF uses an underscore: (key="_foo?bar") is identical to | |||
* (key="_foo.bar", alias1="_foo_bar") | * (key="_foo.bar", alias1="_foo_bar") | |||
*/ | */ | |||
const cif_array * cif_data::get_arr(const char * key, const char * alias1, const char * alias2) const { | const cif_array * cif_data::get_arr(const char * key, const char * alias1, const char * alias2) const { | |||
const char * p; | const char * p; | |||
const char * aliases[] = {alias1, alias2, NULL}; | const char * aliases[] = {alias1, alias2, nullptr}; | |||
m_str_cifarray_t::const_iterator it; | m_str_cifarray_t::const_iterator it; | |||
for (int j = 0; key; key = aliases[j++]) { | for (int j = 0; key; key = aliases[j++]) { | |||
// support alias shortcut: '?' matches '.' and '_' | // support alias shortcut: '?' matches '.' and '_' | |||
if ((p = strchr(key, '?'))) { | if ((p = strchr(key, '?'))) { | |||
std::string tmp(key); | std::string tmp(key); | |||
for (const char * d = "._"; *d; ++d) { | for (const char * d = "._"; *d; ++d) { | |||
// replace '?' by '.' or '_' | // replace '?' by '.' or '_' | |||
tmp[p - key] = *d; | tmp[p - key] = *d; | |||
if ((it = dict.find(tmp.c_str())) != dict.end()) | if ((it = dict.find(tmp.c_str())) != dict.end()) | |||
return &it->second; | return &it->second; | |||
} | } | |||
} else { | } else { | |||
if ((it = dict.find(key)) != dict.end()) | if ((it = dict.find(key)) != dict.end()) | |||
return &it->second; | return &it->second; | |||
} | } | |||
} | } | |||
return NULL; | return nullptr; | |||
} | } | |||
// Get a pointer to array or to a default value if not found | // Get a pointer to array or to a default value if not found | |||
const cif_array * cif_data::get_opt(const char * key, const char * alias1, const char * alias2) const { | const cif_array * cif_data::get_opt(const char * key, const char * alias1, const char * alias2) const { | |||
const cif_array * arr = get_arr(key, alias1, alias2); | const cif_array * arr = get_arr(key, alias1, alias2); | |||
if (arr == NULL) | if (arr == nullptr) | |||
return &EMPTY_ARRAY; | return &EMPTY_ARRAY; | |||
return arr; | return arr; | |||
} | } | |||
// constructor | // constructor | |||
cif_file::cif_file(const char* filename, const char* contents_) { | cif_file::cif_file(const char* filename, const char* contents_) { | |||
if (contents_) { | if (contents_) { | |||
contents = mstrdup(contents_); | contents = mstrdup(contents_); | |||
} else { | } else { | |||
contents = FileGetContents(filename, NULL); | contents = FileGetContents(filename, nullptr); | |||
if (!contents) | if (!contents) | |||
std::cerr << "ERROR: Failed to load file '" << filename << "'" << std::end l; | std::cerr << "ERROR: Failed to load file '" << filename << "'" << std::end l; | |||
} | } | |||
if (contents) | if (contents) | |||
parse(); | parse(); | |||
} | } | |||
// destructor | // destructor | |||
cif_file::~cif_file() { | cif_file::~cif_file() { | |||
for (m_str_cifdatap_t::iterator it = datablocks.begin(), | for (auto& datablock : datablocks) | |||
it_end = datablocks.end(); it != it_end; ++it) | delete datablock.second; | |||
delete it->second; | ||||
if (contents) | if (contents) | |||
mfree(contents); | mfree(contents); | |||
} | } | |||
// destructor | // destructor | |||
cif_data::~cif_data() { | cif_data::~cif_data() { | |||
for (m_str_cifdatap_t::iterator it = saveframes.begin(), | for (auto& saveframe : saveframes) | |||
it_end = saveframes.end(); it != it_end; ++it) | delete saveframe.second; | |||
delete it->second; | ||||
for (auto& loop : loops) | ||||
for (v_cifloopp_t::iterator it = loops.begin(), | delete loop; | |||
it_end = loops.end(); it != it_end; ++it) | ||||
delete *it; | ||||
} | } | |||
// parse CIF contents | // parse CIF contents | |||
bool cif_file::parse() { | bool cif_file::parse() { | |||
char *p = contents; | char *p = contents; | |||
char quote; | char quote; | |||
char prev = '\0'; | char prev = '\0'; | |||
std::vector<bool> keypossible; | std::vector<bool> keypossible; | |||
skipping to change at line 281 | skipping to change at line 278 | |||
*p = 0; | *p = 0; | |||
p += 2; | p += 2; | |||
} | } | |||
prev = ';'; | prev = ';'; | |||
} else { // will null the whitespace | } else { // will null the whitespace | |||
char * q = p++; | char * q = p++; | |||
while (!iswhitespace0(*p)) ++p; | while (!iswhitespace0(*p)) ++p; | |||
prev = *p; | prev = *p; | |||
if (p - q == 1 && (*q == '?' || *q == '.')) { | if (p - q == 1 && (*q == '?' || *q == '.')) { | |||
// store values '.' (inapplicable) and '?' (unknown) as null-pointers | // store values '.' (inapplicable) and '?' (unknown) as null-pointers | |||
q = NULL; | q = nullptr; | |||
keypossible.push_back(false); | keypossible.push_back(false); | |||
} else { | } else { | |||
if (*p) | if (*p) | |||
*(p++) = 0; | *(p++) = 0; | |||
keypossible.push_back(true); | keypossible.push_back(true); | |||
} | } | |||
tokens.push_back(q); | tokens.push_back(q); | |||
} | } | |||
} | } | |||
cif_data *current_data = NULL, *current_frame = NULL, *global_block = NULL; | cif_data *current_data = nullptr, *current_frame = nullptr, *global_block = nu llptr; | |||
// parse into dictionary | // parse into dictionary | |||
for (unsigned int i = 0, n = tokens.size(); i < n; i++) { | for (unsigned int i = 0, n = tokens.size(); i < n; i++) { | |||
if (!keypossible[i]) { | if (!keypossible[i]) { | |||
std::cout << "ERROR" << std::endl; | std::cout << "ERROR" << std::endl; | |||
break; | break; | |||
} else if (tokens[i][0] == '_') { | } else if (tokens[i][0] == '_') { | |||
if (i + 1 == n) { | if (i + 1 == n) { | |||
std::cout << "ERROR truncated" << std::endl; | std::cout << "ERROR truncated" << std::endl; | |||
break; | break; | |||
skipping to change at line 314 | skipping to change at line 311 | |||
if (current_frame) { | if (current_frame) { | |||
tolowerinplace(tokens[i]); | tolowerinplace(tokens[i]); | |||
current_frame->dict[tokens[i]].set_value(tokens[i + 1]); | current_frame->dict[tokens[i]].set_value(tokens[i + 1]); | |||
} | } | |||
i++; | i++; | |||
} else if (strcasecmp("loop_", tokens[i]) == 0) { | } else if (strcasecmp("loop_", tokens[i]) == 0) { | |||
int ncols = 0; | int ncols = 0; | |||
int nrows = 0; | int nrows = 0; | |||
cif_loop *loop = NULL; | cif_loop *loop = nullptr; | |||
// loop data | // loop data | |||
if (current_frame) { | if (current_frame) { | |||
loop = new cif_loop; | loop = new cif_loop; | |||
// add to loops list | // add to loops list | |||
current_frame->loops.push_back(loop); | current_frame->loops.push_back(loop); | |||
} | } | |||
// columns | // columns | |||
End of changes. 12 change blocks. | ||||
20 lines changed or deleted | 17 lines changed or added |