Skip to content

Commit 3435634

Browse files
authored
Merge pull request #415 from CV-GPhL/api-docs/cif
docs: full Doxygen API documentation for CIF handling
2 parents cfc685f + 6535ada commit 3435634

9 files changed

Lines changed: 808 additions & 82 deletions

File tree

‎docs/api.rst‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,33 @@ Map and Grid Data
5454
.. doxygenfile:: model.hpp
5555
:project: gemmi
5656

57+
CIF Data Reading and Writing
58+
-----------------------------
59+
60+
*(Full documentation added in PR 3.)*
61+
62+
.. doxygenfile:: cifdoc.hpp
63+
:project: gemmi
64+
65+
.. doxygenfile:: cif.hpp
66+
:project: gemmi
67+
68+
.. doxygenfile:: read_cif.hpp
69+
:project: gemmi
70+
71+
.. doxygenfile:: to_cif.hpp
72+
:project: gemmi
73+
74+
.. doxygenfile:: to_json.hpp
75+
:project: gemmi
76+
77+
.. doxygenfile:: json.hpp
78+
:project: gemmi
79+
80+
.. doxygenfile:: numb.hpp
81+
:project: gemmi
82+
83+
.. doxygenfile:: ddl.hpp
5784
Structure I/O
5885
-------------
5986

‎include/gemmi/cif.hpp‎

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
/// @file
2+
/// @brief PEGTL-based CIF parser with pluggable action handlers and Document construction.
3+
///
4+
/// This header provides the complete CIF parsing infrastructure:
5+
/// - PEG grammar rules for CIF 1.1 syntax (namespace `rules`)
6+
/// - Customizable action handlers (templates specializing `Action<Rule>`)
7+
/// - Built-in actions that construct an in-memory Document
8+
/// - Entry points: read_file(), read_memory(), read_cstream(), read_istream(), read()
9+
///
10+
/// For high-level parsing of standard formats (mmCIF, plain CIF), prefer read_cif.hpp.
11+
112
// Copyright 2017 Global Phasing Ltd.
213
//
314
// CIF parser (based on PEGTL) with pluggable actions,
@@ -264,10 +275,22 @@ template<> struct Action<rules::loop> {
264275
};
265276

266277

278+
/// @brief Parse CIF content from an input, populating a Document.
279+
/// @tparam Input PEGTL input type (e.g., pegtl::file_input, pegtl::memory_input).
280+
/// @param d Document to populate with parsed blocks and items.
281+
/// @param in PEGTL input object.
282+
/// @throws pegtl::parse_error on syntax errors.
267283
template<typename Input> void parse_input(Document& d, Input&& in) {
268284
pegtl::parse<rules::file, Action, Errors>(in, d);
269285
}
270286

287+
/// @brief Read a complete CIF file and return a Document.
288+
/// @tparam Input PEGTL input type.
289+
/// @param in PEGTL input object with a source() method.
290+
/// @param check_level Validation strictness: 0=no checks, 1=missing values & duplicates, 2=also empty loops.
291+
/// @return Fully parsed Document.
292+
/// @throws pegtl::parse_error on syntax errors.
293+
/// @throws std::runtime_error on validation failures (check_level > 0).
271294
template<typename Input> Document read_input(Input&& in, int check_level=1) {
272295
Document doc;
273296
doc.source = in.source();
@@ -286,6 +309,12 @@ template<typename Input> Document read_input(Input&& in, int check_level=1) {
286309
return doc;
287310
}
288311

312+
/// @brief Parse a single CIF data block and add it to a Document.
313+
/// @tparam Input PEGTL input type.
314+
/// @param d Document to append to.
315+
/// @param in PEGTL input.
316+
/// @return Byte offset after parsing the block.
317+
/// @throws pegtl::parse_error on syntax errors.
289318
template<typename Input>
290319
size_t parse_one_block(Document& d, Input&& in) {
291320
pegtl::parse<rules::one_block, Action, Errors>(in, d);
@@ -302,21 +331,48 @@ size_t parse_one_block(Document& d, Input&& in) {
302331
tao::pegtl::file_input<> in(path)
303332
#endif
304333

334+
/// @brief Read a CIF file from disk.
335+
/// @param filename Path to the CIF file.
336+
/// @param check_level Validation level (0-2).
337+
/// @return Parsed Document.
338+
/// @throws std::runtime_error if file cannot be opened.
339+
/// @throws pegtl::parse_error on syntax errors.
305340
inline Document read_file(const std::string& filename, int check_level=1) {
306341
GEMMI_CIF_FILE_INPUT(in, filename);
307342
return read_input(in, check_level);
308343
}
309344

345+
/// @brief Read CIF from memory.
346+
/// @param data Pointer to CIF content (need not be null-terminated).
347+
/// @param size Number of bytes to parse.
348+
/// @param name Label for error messages (e.g., "buffer").
349+
/// @param check_level Validation level (0-2).
350+
/// @return Parsed Document.
351+
/// @throws pegtl::parse_error on syntax errors.
310352
inline Document read_memory(const char* data, size_t size, const char* name, int check_level=1) {
311353
pegtl::memory_input<> in(data, size, name);
312354
return read_input(in, check_level);
313355
}
314356

357+
/// @brief Read CIF from a C FILE stream.
358+
/// @param f Open FILE pointer (e.g., stdin, or result of fopen()).
359+
/// @param bufsize Buffering size for reading (e.g., 16*1024).
360+
/// @param name Label for error messages.
361+
/// @param check_level Validation level (0-2).
362+
/// @return Parsed Document.
363+
/// @throws pegtl::parse_error on syntax errors.
315364
inline Document read_cstream(std::FILE *f, size_t bufsize, const char* name, int check_level=1) {
316365
pegtl::cstream_input<> in(f, bufsize, name);
317366
return read_input(in, check_level);
318367
}
319368

369+
/// @brief Read CIF from a C++ std::istream.
370+
/// @param is Input stream (e.g., std::ifstream, std::cin).
371+
/// @param bufsize Buffering size (e.g., 16*1024).
372+
/// @param name Label for error messages.
373+
/// @param check_level Validation level (0-2).
374+
/// @return Parsed Document.
375+
/// @throws pegtl::parse_error on syntax errors.
320376
inline Document read_istream(std::istream &is, size_t bufsize, const char* name,
321377
int check_level=1) {
322378
pegtl::istream_input<> in(is, bufsize, name);
@@ -332,6 +388,11 @@ template<> struct CheckAction<rules::missing_value> {
332388
}
333389
};
334390

391+
/// @brief Try parsing CIF without validation or error throwing.
392+
/// @tparam Input PEGTL input type.
393+
/// @param in PEGTL input.
394+
/// @param msg Optional pointer to store error message (if parsing fails).
395+
/// @return true if parse succeeded, false otherwise.
335396
template<typename Input> bool try_parse(Input&& in, std::string* msg) {
336397
try {
337398
return pegtl::parse<rules::file, CheckAction, Errors>(in);
@@ -342,8 +403,13 @@ template<typename Input> bool try_parse(Input&& in, std::string* msg) {
342403
}
343404
}
344405

345-
// A function for transparent reading of normal and compressed files.
346-
// T should have the same traits as BasicInput and MaybeGzipped.
406+
/// @brief Read CIF from a file or stream, handling compression transparently.
407+
/// @tparam T Type with methods: uncompress_into_buffer(), is_stdin(), is_compressed(), path().
408+
/// (Traits matching BasicInput and MaybeGzipped wrappers in Gemmi.)
409+
/// @param input Input wrapper (handles gzip, bzip2, and plain files).
410+
/// @param check_level Validation level (0-2).
411+
/// @return Parsed Document.
412+
/// @throws pegtl::parse_error on syntax errors.
347413
template<typename T>
348414
Document read(T&& input, int check_level=1) {
349415
if (CharArray mem = input.uncompress_into_buffer())
@@ -353,6 +419,11 @@ Document read(T&& input, int check_level=1) {
353419
return read_file(input.path(), check_level);
354420
}
355421

422+
/// @brief Check CIF syntax without building a Document.
423+
/// @tparam T Type with uncompress_into_buffer() and path() methods.
424+
/// @param input Input wrapper.
425+
/// @param msg Optional pointer to store error message.
426+
/// @return true if syntax is valid, false otherwise.
356427
template<typename T>
357428
bool check_syntax(T&& input, std::string* msg) {
358429
if (CharArray mem = input.uncompress_into_buffer()) {
@@ -363,6 +434,13 @@ bool check_syntax(T&& input, std::string* msg) {
363434
return try_parse(in, msg);
364435
}
365436

437+
/// @brief Read one CIF block from a file or stream into an existing Document.
438+
/// @tparam T Type with is_compressed(), is_stdin(), uncompress_into_buffer(size_t), path() methods.
439+
/// @param d Document to append block to.
440+
/// @param input Input wrapper.
441+
/// @param limit Max bytes to read from compressed file (0 = no limit).
442+
/// @return Byte offset after parsing the block.
443+
/// @throws pegtl::parse_error on syntax errors.
366444
template<typename T>
367445
size_t read_one_block(Document& d, T&& input, size_t limit) {
368446
if (input.is_compressed()) {

0 commit comments

Comments
 (0)