.\" 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_input 3" .TH btparse::doc::bt_input 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_input \- input/parsing functions in btparse library .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 10 \& void bt_set_stringopts (bt_metatype_t metatype, btshort options); \& AST * bt_parse_entry_s (char * entry_text, \& char * filename, \& int line, \& btshort options, \& boolean * status); \& AST * bt_parse_entry (FILE * infile, \& char * filename, \& btshort options, \& boolean * status); \& AST * bt_parse_file (char * filename, \& btshort options, \& boolean * overall_status); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The functions described here are used to read and parse BibTeX data, converting it from raw text to abstract-syntax trees (ASTs). .IP "bt_set_stringopts ()" 4 .IX Item "bt_set_stringopts ()" .Vb 1 \& void bt_set_stringopts (bt_metatype_t metatype, btshort options); .Ve .Sp Set the string-processing options for a particular entry metatype. This affects the entry post-processing done by \f(CW\*(C`bt_parse_entry_s()\*(C'\fR, \&\f(CW\*(C`bt_parse_entry()\*(C'\fR, and \f(CW\*(C`bt_parse_file()\*(C'\fR. If \f(CW\*(C`bt_set_stringopts()\*(C'\fR is never called, the four metatypes default to the following sets of string options: .Sp .Vb 4 \& BTE_REGULAR BTO_CONVERT | BTO_EXPAND | BTO_PASTE | BTO_COLLAPSE \& BTE_COMMENT 0 \& BTE_PREAMBLE 0 \& BTE_MACRODEF BTO_CONVERT | BTO_EXPAND | BTO_PASTE .Ve .Sp For example, .Sp .Vb 1 \& bt_set_stringopts (BTE_COMMENT, BTO_COLLAPSE); .Ve .Sp will cause the library to collapse whitespace in the value from all comment entries; the \s-1AST\s0 returned by one of the \f(CW\*(C`bt_parse_*\*(C'\fR functions will reflect this change. .IP "bt_parse_entry ()" 4 .IX Item "bt_parse_entry ()" .Vb 4 \& AST * bt_parse_entry (FILE * infile, \& char * filename, \& btshort options, \& boolean * status); .Ve .Sp Scans and parses the next BibTeX entry in \f(CW\*(C`infile\*(C'\fR. You should supply \&\f(CW\*(C`filename\*(C'\fR to help \fBbtparse\fR generate accurate error messages; the library keeps track of \f(CW\*(C`infile\*(C'\fR's current line number internally, so you don't need to pass that in. \f(CW\*(C`options\*(C'\fR should be a bitmap of non-string-processing options (currently, \f(CW\*(C`BTO_NOSTORE\*(C'\fR to disable storing macro expansions is the only such option). \f(CW*status\fR will be set to \&\f(CW\*(C`TRUE\*(C'\fR if the entry parsed successfully or with only minor warnings, and \&\f(CW\*(C`FALSE\*(C'\fR if there were any serious lexical or syntactic errors. If \&\f(CW\*(C`status\*(C'\fR is \f(CW\*(C`NULL\*(C'\fR, then the parse status will be unavailable to you. Both minor warnings and serious errors are reported on \f(CW\*(C`stderr\*(C'\fR. .Sp Returns a pointer to the abstract-syntax tree (\s-1AST\s0) describing the entry just parsed, or \f(CW\*(C`NULL\*(C'\fR if no more entries were found in \f(CW\*(C`infile\*(C'\fR (this will leave \f(CW\*(C`infile\*(C'\fR at end-of-file). Do not attempt to second guess \&\f(CW\*(C`bt_parse_entry()\*(C'\fR by detecting end-of-file yourself; it must be allowed to determine this on its own so it can clean up some static data that is preserved between calls on the same file. .Sp \&\f(CW\*(C`bt_parse_entry()\*(C'\fR has two important restrictions that you should know about. First, you should let \fBbtparse\fR manage all the input on the file; this is for reasons both superficial (so the library knows the current line number in order to generate accurate error messages) and fundamental (the library must be allowed to detect end-of-file in order to cleanup certain static variables and allow you to parse another file). Second, you cannot interleave the parsing of two different files; attempting to do so will result in a fatal error that will crash your program. This is a direct result of the static state maintained between calls of \f(CW\*(C`bt_parse_entry()\*(C'\fR. .Sp Because of two distinct \*(L"failures\*(R" possible for \f(CW\*(C`bt_parse_entry()\*(C'\fR (end-of-file, which is expected but means to stop processing the current file; and error-in-input, which is not expected but allows you to continue processing the same file), you should usually call it like this: .Sp .Vb 7 \& while (entry = bt_parse_entry (file, filename, options, &ok)) \& { \& if (ok) \& { \& /* ... process entry ... */ \& } \& } .Ve .Sp At the end of this loop, \f(CW\*(C`feof (file)\*(C'\fR will be true. .IP "bt_parse_entry_s ()" 4 .IX Item "bt_parse_entry_s ()" .Vb 5 \& AST * bt_parse_entry_s (char * entry_text, \& char * filename, \& int line, \& btshort options, \& boolean * status) .Ve .Sp Scans and parses a single complete BibTeX entry contained in a string, \&\f(CW\*(C`entry_text\*(C'\fR. If you read this string from a file, you should help \&\fBbtparse\fR generate accurate error messages by supplying the name of the file as \f(CW\*(C`filename\*(C'\fR and the line number of the beginning of the entry as \&\f(CW\*(C`line\*(C'\fR; otherwise, set \f(CW\*(C`filename\*(C'\fR to \f(CW\*(C`NULL\*(C'\fR and \f(CW\*(C`line\*(C'\fR to \f(CW1\fR. \&\f(CW\*(C`options\*(C'\fR and \f(CW\*(C`status\*(C'\fR are the same as for \f(CW\*(C`bt_parse_entry()\*(C'\fR. .Sp Returns a pointer to the abstract-syntax tree (\s-1AST\s0) describing the entry just parsed, and \f(CW\*(C`NULL\*(C'\fR if no entries were found in \f(CW\*(C`entry_text\*(C'\fR or if \&\f(CW\*(C`entry_text\*(C'\fR was \f(CW\*(C`NULL\*(C'\fR. .Sp You should call \f(CW\*(C`bt_parse_entry_s()\*(C'\fR once more than the total number of entries you wish to parse; on the final call, set \f(CW\*(C`entry_text\*(C'\fR to \&\f(CW\*(C`NULL\*(C'\fR so the function knows there's no more text to parse. This final call allows it to clean up some structures allocated on the first call. Thus, \f(CW\*(C`bt_parse_entry_s()\*(C'\fR is usually used like this: .Sp .Vb 4 \& char * entry_text; \& btshort options = 0; \& boolean ok; \& AST * entry_ast; \& \& while (entry_text = get_more_text ()) \& { \& entry_ast = bt_parse_entry_s (entry_text, NULL, 1, options, &ok); \& if (ok) \& { \& /* ... process entry ... */ \& } \& } \& \& bt_parse_entry_s (NULL, NULL, 1, options, NULL); /* cleanup */ .Ve .Sp assuming that \f(CW\*(C`get_more_text()\*(C'\fR returns a pointer to the text of an entry to parse, or \f(CW\*(C`NULL\*(C'\fR if there's no more text available. .IP "bt_parse_file ()" 4 .IX Item "bt_parse_file ()" .Vb 3 \& AST * bt_parse_file (char * filename, \& btshort options, \& boolean * status) .Ve .Sp Scans and parses an entire BibTeX file. If \f(CW\*(C`filename\*(C'\fR is \f(CW\*(C`NULL\*(C'\fR or \&\f(CW"\-"\fR, then \f(CW\*(C`stdin\*(C'\fR will be read; otherwise, attempts to open the named file. If this attempt fails, prints an error message to \f(CW\*(C`stderr\*(C'\fR and returns \f(CW\*(C`NULL\*(C'\fR. \f(CW\*(C`options\*(C'\fR and \f(CW\*(C`status\*(C'\fR are the same as for \&\f(CW\*(C`bt_parse_entry()\*(C'\fR\-\-\-note that \f(CW*status\fR will be \f(CW\*(C`FALSE\*(C'\fR if there were \&\fIany\fR errors in the entire file; for finer granularity of error-checking, you should use \f(CW\*(C`bt_parse_entry()\*(C'\fR. .Sp Returns a pointer to a linked list of ASTs representing the entries in the file, or \f(CW\*(C`NULL\*(C'\fR if no entries were found in the file. This list can be traversed with \f(CW\*(C`bt_next_entry()\*(C'\fR, and the individual entries then traversed as usual (see bt_traversal). .SH "SEE ALSO" .IX Header "SEE ALSO" btparse, bt_postprocess, bt_traversal .SH "AUTHOR" .IX Header "AUTHOR" Greg Ward