.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "btparse::doc::bt_traversal 3" .TH btparse::doc::bt_traversal 3 "2018-11-02" "btparse, version 0.85" "btparse" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" bt_traversal \- AST traversal/query functions in btparse library .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 7 \& 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) .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The functions described here are all used to traverse and query the abstract-syntax trees (ASTs) returned by the input functions described in bt_input. The three \*(L"bt_next\*(R" functions (\f(CW\*(C`bt_next_entry()\*(C'\fR, \&\f(CW\*(C`bt_next_field()\*(C'\fR, and \f(CW\*(C`bt_next_value()\*(C'\fR) are used respectively to traverse a list of entries, the list of fields within a particular entry, and the list of simple values associated with a particular field. The other functions are just used to query various nodes in the tree for the useful information contained in them. .SS "Traversal functions" .IX Subsection "Traversal functions" .IP "\fBbt_next_entry()\fR" 4 .IX Item "bt_next_entry()" .Vb 2 \& AST * bt_next_entry (AST * entry_list, \& AST * prev_entry) .Ve .Sp Used to traverse the linked list of entries returned by \&\f(CW\*(C`bt_parse_file()\*(C'\fR (see bt_input). On the first call, you should supply \f(CW\*(C`NULL\*(C'\fR for \f(CW\*(C`prev_entry\*(C'\fR, and a pointer to the head of the list will be returned. On subsequent calls, pass the previous return value as \f(CW\*(C`prev_entry\*(C'\fR; the function returns the next entry in the list, or \&\f(CW\*(C`NULL\*(C'\fR if there are no more entries. Also returns \f(CW\*(C`NULL\*(C'\fR if either \&\f(CW\*(C`entry_list\*(C'\fR or \f(CW\*(C`prev_entry\*(C'\fR are improper. .Sp For example (ignoring error handling and variable declarations): .Sp .Vb 6 \& entries = bt_parse_file (filename, options, &status); \& entry = NULL; \& while (entry = bt_next_entry (entries, entry)) \& { \& /* process entry */ \& } .Ve .IP "\fBbt_next_field()\fR" 4 .IX Item "bt_next_field()" .Vb 1 \& AST * bt_next_field (AST * entry, AST * prev, char ** name) .Ve .Sp Used to traverse the list of fields in a regular or macro definition entry. (You should call \f(CW\*(C`bt_entry_metatype()\*(C'\fR to determine if you have the right kind of entry before calling \f(CW\*(C`bt_next_field()\*(C'\fR.) \f(CW\*(C`entry\*(C'\fR should be a pointer to the \s-1AST\s0 for a single entry, as returned by \&\f(CW\*(C`bt_parse_entry()\*(C'\fR, \f(CW\*(C`bt_parse_entry_s()\*(C'\fR, or \f(CW\*(C`bt_next_entry()\*(C'\fR. On the first call, supply \f(CW\*(C`NULL\*(C'\fR for \f(CW\*(C`prev\*(C'\fR; \f(CW\*(C`bt_next_field()\*(C'\fR will return a pointer to the first field in \f(CW\*(C`entry\*(C'\fR, or \f(CW\*(C`NULL\*(C'\fR if \f(CW\*(C`entry\*(C'\fR has no fields (for instance, if it's a comment or preamble entry). On subsequent calls, pass the previous return value as \f(CW\*(C`prev\*(C'\fR; \&\f(CW\*(C`bt_next_field()\*(C'\fR will keep returning pointers to field sub-ASTs as long as it makes sense. These pointers can then be passed to \&\f(CW\*(C`bt_next_value()\*(C'\fR or \f(CW\*(C`bt_get_text()\*(C'\fR to get the field's value. .Sp For example, the loop body in the previous example could be: .Sp .Vb 5 \& field = NULL; \& while (field = bt_next_field (entry, field, &field_name)) \& { \& /* process field */ \& } .Ve .IP "\fBbt_next_value()\fR" 4 .IX Item "bt_next_value()" .Vb 4 \& AST * bt_next_value (AST * head, \& AST * prev, \& bt_nodetype_t * nodetype, \& char ** text) .Ve .Sp Traverses the list of simple values that make up the value of a single field. (Recall that a simple value is either a quoted string, a macro invocation, or a number. A compound value is a list of these separated by \f(CW\*(Aq#\*(Aq\fR in the original input. Depending on the string post-processing options used when the data was parsed, the \*(L"list of simple values\*(R" nature of the original data may be preserved in the \s-1AST\s0 that you're traversing, in which case you'll need a \f(CW\*(C`bt_next_value()\*(C'\fR loop. .Sp \&\f(CW\*(C`bt_next_value()\*(C'\fR works much like \f(CW\*(C`bt_next_entry()\*(C'\fR and \&\f(CW\*(C`bt_next_field()\*(C'\fR: on the first call, you supply \f(CW\*(C`NULL\*(C'\fR for \f(CW\*(C`prev\*(C'\fR, and on subsequent calls you supply the previous return value. Returns \&\f(CW\*(C`NULL\*(C'\fR when there are no more simple values to return. Also sets \&\f(CW*nodetype\fR and \f(CW*text\fR to the corresponding information from the simple value node. \f(CW*nodetype\fR will be one of \f(CW\*(C`BTAST_STRING\*(C'\fR, \&\f(CW\*(C`BTAST_MACRO\*(C'\fR, or \f(CW\*(C`BTAST_NUMBER\*(C'\fR; \f(CW*text\fR will point to the same string as the \s-1AST\s0 node does (it is not copied for you), so don't mess with it. .Sp For example, the loop body in the \f(CW\*(C`bt_next_field()\*(C'\fR example could be replaced with: .Sp .Vb 10 \& 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 */ \& } \& } .Ve .Sp See also \*(L"bt_get_text\*(R". .SS "Query functions" .IX Subsection "Query functions" .IP "\fBbt_entry_metatype()\fR" 4 .IX Item "bt_entry_metatype()" .Vb 1 \& bt_metatype_t bt_entry_metatype (AST * entry) .Ve .Sp Returns the metatype of an entry. (Recall that the \fImetatype\fR is an enumerated type whose values are derived from the specific type of an entry; for instance, an \f(CW@comment\fR entry has type \f(CW"comment"\fR and metatype \f(CW\*(C`BTE_COMMENT\*(C'\fR. The type-metatype relationship is similarly obvious for \f(CW\*(C`BTE_PREAMBLE\*(C'\fR; \f(CW\*(C`BTE_MACRODEF\*(C'\fR corresponds to \f(CW@string\fR entries; and \f(CW\*(C`BTE_REGULAR\*(C'\fR corresponds to any other type.) .Sp Returns \f(CW\*(C`BTE_UNKNOWN\*(C'\fR if \f(CW\*(C`entry\*(C'\fR is invalid (i.e., \f(CW\*(C`NULL\*(C'\fR or not a pointer to an entry \s-1AST\s0). .IP "\fBbt_entry_type()\fR" 4 .IX Item "bt_entry_type()" .Vb 1 \& char * bt_entry_type (AST * entry) .Ve .Sp Returns the type of an entry. Recall that the type is the name that appears after the \f(CW\*(Aq@\*(Aq\fR character in the original input. Returns \&\f(CW\*(C`NULL\*(C'\fR if \f(CW\*(C`entry\*(C'\fR is invalid (i.e., \f(CW\*(C`NULL\*(C'\fR or not a pointer to an entry \s-1AST\s0). .IP "\fBbt_entry_key()\fR" 4 .IX Item "bt_entry_key()" .Vb 1 \& char * bt_entry_key (AST * entry) .Ve .Sp 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.) Returns \f(CW\*(C`NULL\*(C'\fR if \f(CW\*(C`entry\*(C'\fR is invalid (i.e., \f(CW\*(C`NULL\*(C'\fR or not a pointer to the \s-1AST\s0 for a regular entry). .IP "\fBbt_get_text()\fR" 4 .IX Item "bt_get_text()" .Vb 1 \& char * bt_get_text (AST * node) .Ve .Sp Performs all string post-processing (macro expansion, concatenation of simple values, and whitespace collapsing) of a compound value and returns the string that results. Can be called either on a field for a regular or macro definition entry (as returned by \f(CW\*(C`bt_next_field()\*(C'\fR), or on a comment or preamble entry. Returns \f(CW\*(C`NULL\*(C'\fR if called on an invalid \s-1AST\s0 node. .SH "SEE ALSO" .IX Header "SEE ALSO" btparse, bt_input, bt_postprocess .SH "AUTHOR" .IX Header "AUTHOR" Greg Ward