1 /* ------------------------------------------------------------------------
2 @NAME : traversal.c
3 @DESCRIPTION: Routines for traversing the AST for a single entry.
4 @GLOBALS :
5 @CALLS :
6 @CREATED : 1997/01/21, Greg Ward
7 @MODIFIED :
8 @VERSION : $Id$
9 @COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
10
11 This file is part of the btparse library. This library is
12 free software; you can redistribute it and/or modify it under
13 the terms of the GNU Library General Public License as
14 published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16 -------------------------------------------------------------------------- */
17 #include "bt_config.h"
18 #include <stdlib.h>
19 #include "btparse.h"
20 #include "parse_auxiliary.h"
21 #include "prototypes.h"
22 #include "my_dmalloc.h"
23
24
bt_next_entry(AST * entry_list,AST * prev_entry)25 AST *bt_next_entry (AST *entry_list, AST *prev_entry)
26 {
27 if (entry_list == NULL || entry_list->nodetype != BTAST_ENTRY)
28 return NULL;
29
30 if (prev_entry)
31 {
32 if (prev_entry->nodetype != BTAST_ENTRY)
33 return NULL;
34 else
35 return prev_entry->right;
36 }
37 else
38 return entry_list;
39 }
40
41
bt_entry_metatype(AST * entry)42 bt_metatype bt_entry_metatype (AST *entry)
43 {
44 if (!entry) return BTE_UNKNOWN;
45 if (entry->nodetype != BTAST_ENTRY)
46 return BTE_UNKNOWN;
47 else
48 return entry->metatype;
49 }
50
51
bt_entry_type(AST * entry)52 char *bt_entry_type (AST *entry)
53 {
54 if (!entry) return NULL;
55 if (entry->nodetype != BTAST_ENTRY)
56 return NULL;
57 else
58 return entry->text;
59 }
60
61
bt_entry_key(AST * entry)62 char *bt_entry_key (AST *entry)
63 {
64 if (entry->metatype == BTE_REGULAR &&
65 entry->down && entry->down->nodetype == BTAST_KEY)
66 {
67 return entry->down->text;
68 }
69 else
70 {
71 return NULL;
72 }
73 }
74
75
bt_next_field(AST * entry,AST * prev,char ** name)76 AST *bt_next_field (AST *entry, AST *prev, char **name)
77 {
78 AST *field;
79 bt_metatype metatype;
80
81 *name = NULL;
82 if (!entry || !entry->down) return NULL; /* protect against empty entry */
83
84 metatype = entry->metatype;
85 if (metatype != BTE_MACRODEF && metatype != BTE_REGULAR)
86 return NULL;
87
88 if (prev == NULL) /* no previous field -- they must */
89 { /* want the first one */
90 field = entry->down;
91 if (metatype == BTE_REGULAR && field->nodetype == BTAST_KEY)
92 field = field->right; /* skip over citation key if present */
93 }
94 else /* they really do want the next one */
95 {
96 field = prev->right;
97 }
98
99 if (!field) return NULL; /* protect against field-less entry */
100 if (name) *name = field->text;
101 return field;
102 } /* bt_next_field() */
103
104
bt_next_macro(AST * entry,AST * prev,char ** name)105 AST *bt_next_macro (AST *entry, AST *prev, char **name)
106 {
107 return bt_next_field (entry, prev, name);
108 }
109
110
bt_next_value(AST * top,AST * prev,bt_nodetype * nodetype,char ** text)111 AST *bt_next_value (AST *top, AST *prev, bt_nodetype *nodetype, char **text)
112 {
113 bt_nodetype nt; /* type of `top' node (to check) */
114 bt_metatype mt;
115 AST * value;
116
117 if (nodetype) *nodetype = BTAST_BOGUS;
118 if (text) *text = NULL;
119
120 if (!top) return NULL;
121 /* get_node_type (top, &nt, &mt); */
122 nt = top->nodetype;
123 mt = top->metatype;
124
125 if ((nt == BTAST_FIELD) ||
126 (nt == BTAST_ENTRY && (mt == BTE_COMMENT || mt == BTE_PREAMBLE)))
127 {
128 if (prev == NULL) /* no previous value -- give 'em */
129 { /* the first one */
130 value = top->down;
131 if (!value) return NULL;
132 if (nodetype) *nodetype = value->nodetype;
133 }
134 else
135 {
136 value = prev->right;
137 if (!value) return NULL;
138 if (nodetype) *nodetype = value->nodetype;
139 }
140
141 if (nt == BTAST_ENTRY && value->nodetype != BTAST_STRING)
142 internal_error ("found comment or preamble with non-string value");
143 }
144 else
145 {
146 value = NULL;
147 }
148
149 if (text && value) *text = value->text;
150
151 return value;
152 } /* bt_next_value() */
153
154
bt_get_text(AST * node)155 char *bt_get_text (AST *node)
156 {
157 btshort pp_options = BTO_FULL; /* options for full processing: */
158 /* expand macros, paste strings, */
159 /* collapse whitespace */
160 bt_nodetype nt;
161 bt_metatype mt;
162
163 nt = node->nodetype;
164 mt = node->metatype;
165
166 if (nt == BTAST_FIELD)
167 {
168 #if DEBUG
169 char *value;
170
171 dump_ast ("bt_get_text (pre): node =\n", node);
172 value = bt_postprocess_field (node, pp_options, FALSE);
173 dump_ast ("bt_get_text (post): node =\n", node);
174 return value;
175 #else
176 return bt_postprocess_field (node, pp_options, FALSE);
177 #endif
178 }
179 else if (nt == BTAST_ENTRY && (mt == BTE_COMMENT || mt == BTE_PREAMBLE))
180 {
181 return bt_postprocess_value (node->down, pp_options, FALSE);
182 }
183 else
184 {
185 return NULL;
186 }
187 }
188