| 1 | // | 
|---|
| 2 | // ipv2.h | 
|---|
| 3 | // | 
|---|
| 4 | // Copyright (C) 1996 Limit Point Systems, Inc. | 
|---|
| 5 | // | 
|---|
| 6 | // Author: Curtis Janssen <cljanss@limitpt.com> | 
|---|
| 7 | // Maintainer: LPS | 
|---|
| 8 | // | 
|---|
| 9 | // This file is part of the SC Toolkit. | 
|---|
| 10 | // | 
|---|
| 11 | // The SC Toolkit is free software; you can redistribute it and/or modify | 
|---|
| 12 | // it under the terms of the GNU Library General Public License as published by | 
|---|
| 13 | // the Free Software Foundation; either version 2, or (at your option) | 
|---|
| 14 | // any later version. | 
|---|
| 15 | // | 
|---|
| 16 | // The SC Toolkit is distributed in the hope that it will be useful, | 
|---|
| 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 19 | // GNU Library General Public License for more details. | 
|---|
| 20 | // | 
|---|
| 21 | // You should have received a copy of the GNU Library General Public License | 
|---|
| 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to | 
|---|
| 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 
|---|
| 24 | // | 
|---|
| 25 | // The U.S. Government is granted a limited license as per AL 91-7. | 
|---|
| 26 | // | 
|---|
| 27 |  | 
|---|
| 28 | #ifndef _util_keyval_ipv2_ipv2_h | 
|---|
| 29 | #define _util_keyval_ipv2_ipv2_h | 
|---|
| 30 | #ifdef __GNUG__ | 
|---|
| 31 | #pragma interface | 
|---|
| 32 | #endif | 
|---|
| 33 |  | 
|---|
| 34 | #include <iostream> | 
|---|
| 35 | #include <util/misc/exenv.h> | 
|---|
| 36 | #include <util/keyval/ipv2_scan.h> | 
|---|
| 37 |  | 
|---|
| 38 | #undef yyFlexLexer | 
|---|
| 39 | #define yyFlexLexer IPV2FlexLexer | 
|---|
| 40 | #include <FlexLexer.h> | 
|---|
| 41 |  | 
|---|
| 42 | namespace sc { | 
|---|
| 43 |  | 
|---|
| 44 | // For temporary data (only used while parsing) | 
|---|
| 45 | /* This integer list is used to keep track of the karray index. */ | 
|---|
| 46 | struct intlist_struct { | 
|---|
| 47 | int i; | 
|---|
| 48 | struct intlist_struct *p; | 
|---|
| 49 | }; | 
|---|
| 50 | typedef struct intlist_struct intlist_t; | 
|---|
| 51 |  | 
|---|
| 52 | // For permanent data | 
|---|
| 53 | struct ip_keyword_tree_struct { | 
|---|
| 54 | char *keyword; | 
|---|
| 55 | char *classname; | 
|---|
| 56 | char *truename; | 
|---|
| 57 | struct ip_keyword_tree_struct *across; /* Circular list. */ | 
|---|
| 58 | struct ip_keyword_tree_struct *up;    /* Terminated by NULL. */ | 
|---|
| 59 | struct ip_keyword_tree_struct *down;  /* Terminated by NULL. */ | 
|---|
| 60 | char *variable;  /* If this node points to another name, this | 
|---|
| 61 | * is the name, otherwise NULL. */ | 
|---|
| 62 | char *value; | 
|---|
| 63 | int seen; | 
|---|
| 64 | }; | 
|---|
| 65 |  | 
|---|
| 66 | struct ip_keyword_tree_list_struct { | 
|---|
| 67 | struct ip_keyword_tree_struct *kt; | 
|---|
| 68 | struct ip_keyword_tree_list_struct *p; | 
|---|
| 69 | }; | 
|---|
| 70 |  | 
|---|
| 71 | struct ip_cwk_stack_struct { | 
|---|
| 72 | struct ip_keyword_tree_list_struct *ktl; | 
|---|
| 73 | struct ip_cwk_stack_struct *p; | 
|---|
| 74 | }; | 
|---|
| 75 | typedef struct ip_cwk_stack_struct ip_cwk_stack_t; | 
|---|
| 76 |  | 
|---|
| 77 | typedef struct ip_keyword_tree_struct ip_keyword_tree_t; | 
|---|
| 78 | typedef struct ip_keyword_tree_list_struct ip_keyword_tree_list_t; | 
|---|
| 79 |  | 
|---|
| 80 | class IPV2 | 
|---|
| 81 | { | 
|---|
| 82 | public: | 
|---|
| 83 | enum Status { | 
|---|
| 84 | OK=0          ,  /* No problem. */ | 
|---|
| 85 | KeyNotFound=1 ,  /* The keyword was not found. */ | 
|---|
| 86 | OutOfBounds=2 ,  /* An array subscript was out of bounds. */ | 
|---|
| 87 | Malloc=3      ,  /* Memory allocation failed. */ | 
|---|
| 88 | NotAnArray=4  ,  /* Gave index for data which isn't an array */ | 
|---|
| 89 | NotAScalar=5  ,  /* Didn't give index for data which is an array */ | 
|---|
| 90 | Type=6        ,  /* The datum is not of the appropiate type. */ | 
|---|
| 91 | HasNoValue=7  ,  /* The keyword has no value. */ | 
|---|
| 92 | ValNotExpd=8     /* A value was not expected for the keyword. */ | 
|---|
| 93 | }; | 
|---|
| 94 | enum { KEYWORD_LENGTH=256 }; | 
|---|
| 95 |  | 
|---|
| 96 | private: | 
|---|
| 97 | char *filename_; | 
|---|
| 98 |  | 
|---|
| 99 | // These are needed only when the input is being read in: | 
|---|
| 100 | ip_string_list_t* table_keywords; | 
|---|
| 101 | ip_string_list_t* current_table_keyword; | 
|---|
| 102 | ip_keyword_tree_t* table_sub_tree; | 
|---|
| 103 | int table_row_number; | 
|---|
| 104 | int table_array_depth; | 
|---|
| 105 | intlist_t *karray_indices; | 
|---|
| 106 | ip_keyword_tree_t *sub_tree; | 
|---|
| 107 | int init_karray; | 
|---|
| 108 |  | 
|---|
| 109 | // this maintains a list of current working keyword lists (for cwk_push | 
|---|
| 110 | // and cwk_pop) | 
|---|
| 111 | ip_cwk_stack_t *cwkstack; | 
|---|
| 112 |  | 
|---|
| 113 | // This keeps track of whether or not we've been initialized | 
|---|
| 114 | int ip_initialized; | 
|---|
| 115 |  | 
|---|
| 116 | // This is used for error processing | 
|---|
| 117 | char lastkeyword[KEYWORD_LENGTH]; | 
|---|
| 118 |  | 
|---|
| 119 | // These are needed always: | 
|---|
| 120 | std::istream* ip_in; | 
|---|
| 121 | std::ostream* ip_out; | 
|---|
| 122 | ip_keyword_tree_t* ip_tree; | 
|---|
| 123 | ip_keyword_tree_list_t* ip_cwk; | 
|---|
| 124 | int ip_keyword; | 
|---|
| 125 |  | 
|---|
| 126 | // private routines mainly used for parsing the input | 
|---|
| 127 | void ip_push_table_col(char*); | 
|---|
| 128 | void ip_next_table_entry(); | 
|---|
| 129 | char* dup_string(const char*); | 
|---|
| 130 | ip_keyword_tree_t* ip_get_variable_kt(char*); | 
|---|
| 131 | char* ip_get_variable_value(char*); | 
|---|
| 132 | void ip_internal_values(); | 
|---|
| 133 | void ip_push_keyword(char*); | 
|---|
| 134 | void ip_push_keyclass(char*,char*,ip_string_list_t*); | 
|---|
| 135 | void ip_pop_keyword(); | 
|---|
| 136 | void ip_begin_table(ip_string_list_t*); | 
|---|
| 137 | void ip_done_table(); | 
|---|
| 138 | ip_string_list_t* ip_add_string_list(ip_string_list_t*,char*); | 
|---|
| 139 | ip_string_list_t* ip_string_to_string_list(char*); | 
|---|
| 140 | void ip_assign_variable(char*); | 
|---|
| 141 | double ip_get_variable_double(char*); | 
|---|
| 142 | char* ip_double_to_string(double); | 
|---|
| 143 | void ip_assign_value(char*value); | 
|---|
| 144 | void ip_start_karray(); | 
|---|
| 145 | void ip_init_karray(); | 
|---|
| 146 | void ip_incr_karray(); | 
|---|
| 147 | void ip_lastkeyword(const char*); | 
|---|
| 148 | void ip_lastkeywordtree(ip_keyword_tree_t*); | 
|---|
| 149 | void ip_lastkeyword_(ip_keyword_tree_t*); | 
|---|
| 150 | ip_keyword_tree_t* ip_alloc_keyword_tree(); | 
|---|
| 151 | void ip_free_keyword_tree(ip_keyword_tree_t*); | 
|---|
| 152 | void ip_cwk_add_kt(ip_keyword_tree_t*); | 
|---|
| 153 | ip_keyword_tree_t* ip_cwk_descend_tree(const char*); | 
|---|
| 154 | ip_keyword_tree_t* ip_descend_tree(ip_keyword_tree_t*,const char*); | 
|---|
| 155 | char* ip_key_value(const char*); | 
|---|
| 156 | void free_keyword_tree_list(ip_keyword_tree_list_t*); | 
|---|
| 157 | ip_keyword_tree_list_t* splice_keyword_tree_list(ip_keyword_tree_t*, | 
|---|
| 158 | ip_keyword_tree_list_t*); | 
|---|
| 159 | void ip_cwk_karray_add_v(int,int*); | 
|---|
| 160 | void ip_cwk_karray_add(int,...); | 
|---|
| 161 | ip_keyword_tree_t* ip_karray_descend_v(ip_keyword_tree_t*,int,int*); | 
|---|
| 162 | ip_keyword_tree_t* ip_karray_descend(ip_keyword_tree_t*,int,...); | 
|---|
| 163 | void print_tree_(std::ostream&,ip_keyword_tree_t*); | 
|---|
| 164 | int ip_special_characters(char*); | 
|---|
| 165 | char* ip_append_keystrings(char*,char*); | 
|---|
| 166 | void ip_pop_karray(); | 
|---|
| 167 | void ip_initialize(std::istream&,std::ostream&); | 
|---|
| 168 | void ip_append(std::istream&,std::ostream&); | 
|---|
| 169 | char* get_truename(ip_keyword_tree_t*kt); | 
|---|
| 170 |  | 
|---|
| 171 | void showpos(); | 
|---|
| 172 |  | 
|---|
| 173 | IPV2FlexLexer *lexer; | 
|---|
| 174 |  | 
|---|
| 175 | int ylex() { return lexer->yylex(); } | 
|---|
| 176 | int yparse(); | 
|---|
| 177 | void yerror(const char* s); | 
|---|
| 178 |  | 
|---|
| 179 | public: | 
|---|
| 180 | IPV2(); | 
|---|
| 181 | virtual ~IPV2(); | 
|---|
| 182 | static int have_global(); | 
|---|
| 183 | static void set_global(IPV2*); | 
|---|
| 184 | static IPV2* global(); | 
|---|
| 185 | // calls either ip_append or ip_initialize based on ip_initialized | 
|---|
| 186 | void read(std::istream&,std::ostream&,const char *filename=0); | 
|---|
| 187 | void append_from_input(const char*,std::ostream&); | 
|---|
| 188 | void done(); | 
|---|
| 189 | const char* error_message(IPV2::Status); | 
|---|
| 190 | void error(const char*); | 
|---|
| 191 | void warn(const char*); | 
|---|
| 192 | void cwk_root(); | 
|---|
| 193 | void cwk_clear(); | 
|---|
| 194 | void cwk_add(const char*); | 
|---|
| 195 | void cwk_push(); | 
|---|
| 196 | void cwk_pop(); | 
|---|
| 197 | IPV2::Status boolean(const char*,int*,int,...); | 
|---|
| 198 | IPV2::Status boolean_v(const char*,int*,int,int*); | 
|---|
| 199 | int exist(const char*,int,...); | 
|---|
| 200 | int exist_v(const char*,int,int*); | 
|---|
| 201 | IPV2::Status data(const char*,const char*,void*,int,...); | 
|---|
| 202 | IPV2::Status data_v(const char*,const char*,void*,int,int*); | 
|---|
| 203 | // the character string produced by classname must not be delete[]'ed | 
|---|
| 204 | IPV2::Status classname(const char*,const char**,int,...); | 
|---|
| 205 | IPV2::Status classname_v(const char*,const char**,int,int*); | 
|---|
| 206 | // the character string produced by truekeyword must not be delete[]'ed | 
|---|
| 207 | // if there is no alias for the keyword the string pointer is set to | 
|---|
| 208 | // null and if the keyword exists OK is returned | 
|---|
| 209 | IPV2::Status truekeyword(const char*,const char**,int,...); | 
|---|
| 210 | IPV2::Status truekeyword_v(const char*,const char**,int,int*); | 
|---|
| 211 | IPV2::Status string(const char*,char**,int,...); | 
|---|
| 212 | IPV2::Status string_v(const char*,char**,int,int*); | 
|---|
| 213 | // the character string produced by value must not be delete[]'ed | 
|---|
| 214 | // or free'ed. | 
|---|
| 215 | IPV2::Status value(const char*,const char**,int,...); | 
|---|
| 216 | IPV2::Status value_v(const char*,const char**,int,int*); | 
|---|
| 217 |  | 
|---|
| 218 | IPV2::Status construct_key_v(const char*,char*,int,int*); | 
|---|
| 219 | IPV2::Status count(const char*,int*,int,...); | 
|---|
| 220 | IPV2::Status count_v(const char*,int*,int,int*); | 
|---|
| 221 |  | 
|---|
| 222 | // some routines for debugging | 
|---|
| 223 | void print_keyword(std::ostream&f=ExEnv::out0(),ip_keyword_tree_t*k=0); | 
|---|
| 224 | void print_tree(std::ostream&f=ExEnv::out0(),ip_keyword_tree_t*k=0); | 
|---|
| 225 | void print_unseen(std::ostream&f=ExEnv::out0(),ip_keyword_tree_t*k=0); | 
|---|
| 226 | int have_unseen(ip_keyword_tree_t*k=0); | 
|---|
| 227 | }; | 
|---|
| 228 |  | 
|---|
| 229 | } | 
|---|
| 230 |  | 
|---|
| 231 | #endif | 
|---|
| 232 |  | 
|---|
| 233 | // Local Variables: | 
|---|
| 234 | // mode: c++ | 
|---|
| 235 | // c-file-style: "CLJ" | 
|---|
| 236 | // End: | 
|---|