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 }