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