btparse::doc::bt_traversal(3)
β¨ NAME β¨
bt_traversal β the AST traversal/query functions in the btparse library, aka the little tour guides that walk you around your parse tree π§
πΈ SYNOPSIS πΈ
AST * bt_next_entry (AST * entry_list,
AST * prev_entry)
AST * bt_next_field (AST * entry, AST * prev, char ** name)
AST * bt_next_value (AST * head,
AST * prev,
bt_nodetype_t * nodetype,
char ** text)
bt_metatype_t bt_entry_metatype (AST * entry)
char * bt_entry_type (AST * entry)
char * bt_entry_key (AST * entry)
char * bt_get_text (AST * node)
π DESCRIPTION π
okay bestie, so every single function in here is about walking around and asking questions of the abstract-syntax trees (ASTs) that the input functions give you back β those input functions live over in bt_input, go say hi.
The three "bt_next" girlies β bt_next_entry(), bt_next_field(), and bt_next_value() β are your tour guides. Respectively they take you through a list of entries, through the list of fields inside one particular entry, and through the list of simple values hanging off one particular field. The rest of the functions? They're the gossip girls β they just query the various nodes in the tree for the useful info tucked inside them. π
π₯ Traversal functions π₯
bt_next_entry()
AST * bt_next_entry (AST * entry_list,
AST * prev_entry)
This one walks the linked list of entries that bt_parse_file() handed you (again, see bt_input). First call? Pass NULL for prev_entry and boom, you get back a pointer to the head of the list. Every call after that, pass the previous return value as prev_entry, and it gives you the next entry in the list β or NULL if there are literally no more entries left. It also returns NULL if either entry_list or prev_entry is improper, so likeβ¦ mind your manners. π
Example time (ignoring error handling and variable declarations, because we're being casual):
entries = bt_parse_file (filename, options, &status);
entry = NULL;
while (entry = bt_next_entry (entries, entry))
{
/* process entry */
}
bt_next_field()
AST * bt_next_field (AST * entry, AST * prev, char ** name)
Walks the list of fields inside a regular or macro definition entry. Heads up though β you should call bt_entry_metatype() first to check you've actually got the right kind of entry before you go calling bt_next_field(). Rude to assume. β
entry should be a pointer to the AST for a single entry, as returned by bt_parse_entry(), bt_parse_entry_s(), or bt_next_entry(). First call, supply NULL for prev; bt_next_field() returns a pointer to the first field in entry, or NULL if entry has no fields (say, if it's a comment or preamble entry β some entries just don't have field energy). Subsequent calls: pass the previous return value as prev, and it keeps returning pointers to field sub-ASTs as long as it makes sense to. Those pointers can then be passed to bt_next_value() or bt_get_text() to get the field's actual value. π
For example, the loop body in the previous example could be:
field = NULL;
while (field = bt_next_field (entry, field, &field_name))
{
/* process field */
}
bt_next_value()
AST * bt_next_value (AST * head,
AST * prev,
bt_nodetype_t * nodetype,
char ** text)
Traverses the list of simple values that make up the value of one single field. Quick refresher, bestie: a simple value is either a quoted string, a macro invocation, or a number. A compound value is a list of those separated by # in the original input. Depending on the string post-processing options used when the data was parsed, that "list of simple values" nature of the original data may still be preserved in the AST you're traversing β and if it is, you're gonna need a bt_next_value() loop. Periodt.
bt_next_value() works a lot like bt_next_entry() and bt_next_field(): first call you supply NULL for prev, and on the calls after that you supply the previous return value. It returns NULL when there are no more simple values to give you. It also sets *nodetype and *text to the corresponding information from the simple value node. *nodetype will be one of BTAST_STRING, BTAST_MACRO, or BTAST_NUMBER; *text will point to the same string the AST node does (it is not copied for you, okay?!) so do NOT mess with it. π«Ά
For example, the loop body in the bt_next_field() example could be replaced with:
value = NULL;
while (value = bt_next_field (field, value, &nodetype, &text))
{
switch (nodetype)
{
case BTAST_STRING: /* process the string */
case BTAST_MACRO: /* process the macro */
case BTAST_NUMBER: /* process the number */
}
}
See also bt_get_text β it's giving related. π
π Query functions π
bt_entry_metatype()
bt_metatype_t bt_entry_metatype (AST * entry)
Returns the metatype of an entry. Recall that the metatype is an enumerated type whose values are derived from the specific type of an entry β so like, an @comment entry has type comment and metatype BTE_COMMENT. The type-metatype relationship is similarly obvious for BTE_PREAMBLE; BTE_MACRODEF corresponds to @string entries; and BTE_REGULAR corresponds to any other type.
Returns BTE_UNKNOWN if entry is invalid (i.e., NULL or not a pointer to an entry AST). Not me getting an unknown metatype π
bt_entry_type()
char * bt_entry_type (AST * entry)
Returns the type of an entry. Remember, the type is the name that shows up after the @ character in the original input. Returns NULL if entry is invalid (i.e., NULL or not a pointer to an entry AST).
bt_entry_key()
char * bt_entry_key (AST * entry)
Returns the citation key of a regular entry. (The citation key is the name that appears after the entry-open delimiter in a regular entry β yeah, that one.) Returns NULL if entry is invalid (i.e., NULL or not a pointer to the AST for a regular entry).
bt_get_text()
char * bt_get_text (AST * node)
Does all the string post-processing β macro expansion, concatenation of simple values, and whitespace collapsing β on a compound value, and returns the resulting string. Iconic behaviour honestly. β¨
You can call it either on a field of a regular or macro definition entry (as returned by bt_next_field()), or on a comment or preamble entry. Returns NULL if you call it on an invalid AST node. Vibe check failed, sorry. π
π SEE ALSO π
btparse, bt_input, bt_postprocess
π«Ά AUTHOR π«Ά
Greg Ward <gward@python.net> β thank you for your service, king π
no cap, that's the whole page bestie π go traverse some trees, you've got this
btparse, version 0.91 β 2025-01-31 πΈ that's the source, the version, and the date, all wrapped up with a lil bow. byeee π
π¦ where this page comes from
- debian trixie: libbtparse-dev 0.91-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libbtparse-dev 0.91-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms