1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//  file:  rbbistbl.cpp    Implementation of the ICU RBBISymbolTable class
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru***************************************************************************
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Copyright (C) 2002-2006 International Business Machines Corporation   *
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   and others. All rights reserved.                                      *
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru***************************************************************************
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_BREAK_ITERATION
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/unistr.h"
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uniset.h"
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/parsepos.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "umutex.h"
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "rbbirb.h"
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "rbbinode.h"
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//  RBBISymbolTableEntry_deleter    Used by the UHashTable to delete the contents
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                  when the hash table is deleted.
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_BEGIN
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV RBBISymbolTableEntry_deleter(void *p) {
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    U_NAMESPACE_QUALIFIER RBBISymbolTableEntry *px = (U_NAMESPACE_QUALIFIER RBBISymbolTableEntry *)p;
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete px;
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_END
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRBBISymbolTable::RBBISymbolTable(RBBIRuleScanner *rs, const UnicodeString &rules, UErrorCode &status)
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    :fRules(rules), fRuleScanner(rs), ffffString(UChar(0xffff))
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fHashTable       = NULL;
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fCachedSetLookup = NULL;
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fHashTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status);
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // uhash_open checks status
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uhash_setValueDeleter(fHashTable, RBBISymbolTableEntry_deleter);
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRBBISymbolTable::~RBBISymbolTable()
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uhash_close(fHashTable);
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//  RBBISymbolTable::lookup       This function from the abstract symbol table inteface
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                looks up a variable name and returns a UnicodeString
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                containing the substitution text.
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                The variable name does NOT include the leading $.
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UnicodeString  *RBBISymbolTable::lookup(const UnicodeString& s) const
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBISymbolTableEntry  *el;
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBINode              *varRefNode;
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBINode              *exprNode;
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBINode              *usetNode;
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UnicodeString   *retString;
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBISymbolTable       *This = (RBBISymbolTable *)this;   // cast off const
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    el = (RBBISymbolTableEntry *)uhash_get(fHashTable, &s);
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (el == NULL) {
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    varRefNode = el->val;
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    exprNode   = varRefNode->fLeftChild;     // Root node of expression for variable
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (exprNode->fType == RBBINode::setRef) {
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // The $variable refers to a single UnicodeSet
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        //   return the ffffString, which will subsequently be interpreted as a
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        //   stand-in character for the set by RBBISymbolTable::lookupMatcher()
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        usetNode = exprNode->fLeftChild;
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        This->fCachedSetLookup = usetNode->fInputSet;
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        retString = &ffffString;
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // The variable refers to something other than just a set.
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // return the original source string for the expression
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        retString = &exprNode->fText;
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        This->fCachedSetLookup = NULL;
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return retString;
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//  RBBISymbolTable::lookupMatcher   This function from the abstract symbol table
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   interface maps a single stand-in character to a
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   pointer to a Unicode Set.   The Unicode Set code uses this
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   mechanism to get all references to the same $variable
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   name to refer to a single common Unicode Set instance.
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//    This implementation cheats a little, and does not maintain a map of stand-in chars
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//    to sets.  Instead, it takes advantage of the fact that  the UnicodeSet
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//    constructor will always call this function right after calling lookup(),
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//    and we just need to remember what set to return between these two calls.
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UnicodeFunctor *RBBISymbolTable::lookupMatcher(UChar32 ch) const
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeSet *retVal = NULL;
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBISymbolTable *This = (RBBISymbolTable *)this;   // cast off const
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (ch == 0xffff) {
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        retVal = fCachedSetLookup;
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        This->fCachedSetLookup = 0;
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return retVal;
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// RBBISymbolTable::parseReference   This function from the abstract symbol table interface
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   looks for a $variable name in the source text.
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   It does not look it up, only scans for it.
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   It is used by the UnicodeSet parser.
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   This implementation is lifted pretty much verbatim
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   from the rules based transliterator implementation.
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                   I didn't see an obvious way of sharing it.
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString   RBBISymbolTable::parseReference(const UnicodeString& text,
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                ParsePosition& pos, int32_t limit) const
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t start = pos.getIndex();
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i = start;
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString result;
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (i < limit) {
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar c = text.charAt(i);
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if ((i==start && !u_isIDStart(c)) || !u_isIDPart(c)) {
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ++i;
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (i == start) { // No valid name chars
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return result; // Indicate failure with empty string
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    pos.setIndex(i);
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    text.extractBetween(start, i, result);
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// RBBISymbolTable::lookupNode      Given a key (a variable name), return the
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                  corresponding RBBI Node.  If there is no entry
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                  in the table for this name, return NULL.
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRBBINode       *RBBISymbolTable::lookupNode(const UnicodeString &key) const{
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBINode             *retNode = NULL;
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBISymbolTableEntry *el;
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    el = (RBBISymbolTableEntry *)uhash_get(fHashTable, &key);
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (el != NULL) {
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        retNode = el->val;
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return retNode;
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//    RBBISymbolTable::addEntry     Add a new entry to the symbol table.
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                  Indicate an error if the name already exists -
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                    this will only occur in the case of duplicate
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                                    variable assignments.
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid            RBBISymbolTable::addEntry  (const UnicodeString &key, RBBINode *val, UErrorCode &err) {
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBISymbolTableEntry *e;
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* test for buffer overflows */
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(err)) {
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    e = (RBBISymbolTableEntry *)uhash_get(fHashTable, &key);
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (e != NULL) {
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        err = U_BRK_VARIABLE_REDFINITION;
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    e = new RBBISymbolTableEntry;
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (e == NULL) {
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        err = U_MEMORY_ALLOCATION_ERROR;
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    e->key = key;
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    e->val = val;
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uhash_put( fHashTable, &e->key, e, &err);
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRBBISymbolTableEntry::RBBISymbolTableEntry() : UMemory(), key(), val(NULL) {}
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRBBISymbolTableEntry::~RBBISymbolTableEntry() {
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // The "val" of a symbol table entry is a variable reference node.
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // The l. child of the val is the rhs expression from the assignment.
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Unlike other node types, children of variable reference nodes are not
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //    automatically recursively deleted.  We do it manually here.
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete val->fLeftChild;
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    val->fLeftChild = NULL;
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete  val;
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Note: the key UnicodeString is destructed by virtue of being in the object by value.
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//  RBBISymbolTable::print    Debugging function, dump out the symbol table contents.
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef RBBI_DEBUG
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid RBBISymbolTable::rbbiSymtablePrint() const {
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("Variable Definitions\n"
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           "Name               Node Val     String Val\n"
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           "----------------------------------------------------------------------\n");
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t pos = -1;
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UHashElement  *e   = NULL;
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (;;) {
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        e = uhash_nextElement(fHashTable,  &pos);
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (e == NULL ) {
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBISymbolTableEntry  *s   = (RBBISymbolTableEntry *)e->value.pointer;
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBI_DEBUG_printUnicodeString(s->key, 15);
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBIDebugPrintf("   %8p   ", (void *)s->val);
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBI_DEBUG_printUnicodeString(s->val->fLeftChild->fText);
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBIDebugPrintf("\n");
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("\nParsed Variable Definitions\n");
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    pos = -1;
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (;;) {
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        e = uhash_nextElement(fHashTable,  &pos);
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (e == NULL ) {
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBISymbolTableEntry  *s   = (RBBISymbolTableEntry *)e->value.pointer;
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBI_DEBUG_printUnicodeString(s->key);
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        s->val->fLeftChild->printTree(TRUE);
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBIDebugPrintf("\n");
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
270