File indexing completed on 2025-01-26 04:44:01
0001 /* ------------------------------------------------------------------------ 0002 @NAME : traversal.c 0003 @DESCRIPTION: Routines for traversing the AST for a single entry. 0004 @GLOBALS : 0005 @CALLS : 0006 @CREATED : 1997/01/21, Greg Ward 0007 @MODIFIED : 0008 @VERSION : $Id: traversal.c,v 1.17 1999/11/29 01:13:10 greg Rel $ 0009 @COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved. 0010 0011 This file is part of the btparse library. This library is 0012 free software; you can redistribute it and/or modify it under 0013 the terms of the GNU General Public License as 0014 published by the Free Software Foundation; either version 2 0015 of the License, or (at your option) any later version. 0016 -------------------------------------------------------------------------- */ 0017 #include "bt_debug.h" 0018 #include <stdlib.h> 0019 #include "btparse.h" 0020 #include "parse_auxiliary.h" 0021 #include "prototypes.h" 0022 /*#include "my_dmalloc.h"*/ 0023 0024 0025 AST *bt_next_entry (AST *entry_list, AST *prev_entry) 0026 { 0027 if (entry_list == NULL || entry_list->nodetype != BTAST_ENTRY) 0028 return NULL; 0029 0030 if (prev_entry) 0031 { 0032 if (prev_entry->nodetype != BTAST_ENTRY) 0033 return NULL; 0034 else 0035 return prev_entry->right; 0036 } 0037 else 0038 return entry_list; 0039 } 0040 0041 0042 bt_metatype bt_entry_metatype (AST *entry) 0043 { 0044 if (!entry) return BTE_UNKNOWN; 0045 if (entry->nodetype != BTAST_ENTRY) 0046 return BTE_UNKNOWN; 0047 else 0048 return entry->metatype; 0049 } 0050 0051 0052 char *bt_entry_type (AST *entry) 0053 { 0054 if (!entry) return NULL; 0055 if (entry->nodetype != BTAST_ENTRY) 0056 return NULL; 0057 else 0058 return entry->text; 0059 } 0060 0061 0062 char *bt_entry_key (AST *entry) 0063 { 0064 if (entry->metatype == BTE_REGULAR && 0065 entry->down && entry->down->nodetype == BTAST_KEY) 0066 { 0067 return entry->down->text; 0068 } 0069 else 0070 { 0071 return NULL; 0072 } 0073 } 0074 0075 0076 AST *bt_next_field (AST *entry, AST *prev, char **name) 0077 { 0078 AST *field; 0079 bt_metatype metatype; 0080 0081 *name = NULL; 0082 if (!entry || !entry->down) return NULL; /* protect against empty entry */ 0083 0084 metatype = entry->metatype; 0085 if (metatype != BTE_MACRODEF && metatype != BTE_REGULAR) 0086 return NULL; 0087 0088 if (prev == NULL) /* no previous field -- they must */ 0089 { /* want the first one */ 0090 field = entry->down; 0091 if (metatype == BTE_REGULAR && field->nodetype == BTAST_KEY) 0092 field = field->right; /* skip over citation key if present */ 0093 } 0094 else /* they really do want the next one */ 0095 { 0096 field = prev->right; 0097 } 0098 0099 if (!field) return NULL; /* protect against field-less entry */ 0100 if (name) *name = field->text; 0101 return field; 0102 } /* bt_next_field() */ 0103 0104 0105 AST *bt_next_macro (AST *entry, AST *prev, char **name) 0106 { 0107 return bt_next_field (entry, prev, name); 0108 } 0109 0110 0111 AST *bt_next_value (AST *top, AST *prev, bt_nodetype *nodetype, char **text) 0112 { 0113 bt_nodetype nt; /* type of `top' node (to check) */ 0114 bt_metatype mt; 0115 AST * value; 0116 0117 if (nodetype) *nodetype = BTAST_BOGUS; 0118 if (text) *text = NULL; 0119 0120 if (!top) return NULL; 0121 /* get_node_type (top, &nt, &mt); */ 0122 nt = top->nodetype; 0123 mt = top->metatype; 0124 0125 if ((nt == BTAST_FIELD) || 0126 (nt == BTAST_ENTRY && (mt == BTE_COMMENT || mt == BTE_PREAMBLE))) 0127 { 0128 if (prev == NULL) /* no previous value -- give 'em */ 0129 { /* the first one */ 0130 value = top->down; 0131 if (!value) return NULL; 0132 if (nodetype) *nodetype = value->nodetype; 0133 } 0134 else 0135 { 0136 value = prev->right; 0137 if (!value) return NULL; 0138 if (nodetype) *nodetype = value->nodetype; 0139 } 0140 0141 if (nt == BTAST_ENTRY && value->nodetype != BTAST_STRING) 0142 internal_error ("found comment or preamble with non-string value"); 0143 } 0144 else 0145 { 0146 value = NULL; 0147 } 0148 0149 if (text && value) *text = value->text; 0150 0151 return value; 0152 } /* bt_next_value() */ 0153 0154 0155 char *bt_get_text (AST *node) 0156 { 0157 ushort pp_options = BTO_FULL; /* options for full processing: */ 0158 /* expand macros, paste strings, */ 0159 /* collapse whitespace */ 0160 bt_nodetype nt; 0161 bt_metatype mt; 0162 0163 nt = node->nodetype; 0164 mt = node->metatype; 0165 0166 if (nt == BTAST_FIELD) 0167 { 0168 #if DEBUG 0169 char *value; 0170 0171 dump_ast ("bt_get_text (pre): node =\n", node); 0172 value = bt_postprocess_field (node, pp_options, FALSE); 0173 dump_ast ("bt_get_text (post): node =\n", node); 0174 return value; 0175 #else 0176 return bt_postprocess_field (node, pp_options, FALSE); 0177 #endif 0178 } 0179 else if (nt == BTAST_ENTRY && (mt == BTE_COMMENT || mt == BTE_PREAMBLE)) 0180 { 0181 return bt_postprocess_value (node->down, pp_options, FALSE); 0182 } 0183 else 0184 { 0185 return NULL; 0186 } 0187 }