Tooltalk fixes for OpenBSD. This consists mainly of #ifdefs, casts and some small...
[oweals/cde.git] / cde / lib / tt / lib / util / tt_string_map.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 //%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                  
24 //%%  (c) Copyright 1993, 1994 International Business Machines Corp.    
25 //%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                   
26 //%%  (c) Copyright 1993, 1994 Novell, Inc.                             
27 //%%  $TOG: tt_string_map.C /main/10 1999/10/14 18:42:44 mgreess $ 
28
29 /* @(#)tt_string_map.C  1.10 95/01/06
30  *
31  * Tool Talk Utility
32  *
33  * Copyright (c) 1990 by Sun Microsystems, Inc.
34  *
35  * Defines a class for holding string maps.  This
36  * class is used for 2 different things at this time:
37  *
38  *      _Tt_db_hostname_redirection_map
39  *      _Tt_db_partition_redirection_map
40  */
41 #include <fcntl.h>
42 #include "util/tt_string_map.h"
43 #include "util/tt_map_entry.h"
44
45 /* Included after "util/tt_string.h" to avoid index/strchr conflicts. */
46 #define X_INCLUDE_STRING_H
47 #define XOS_USE_NO_LOCKING
48 #if defined(linux) || defined(CSRG_BASED)
49 #define index
50 #define rindex
51 #endif
52 #include <X11/Xos_r.h>
53 #if defined(linux) || defined(CSRG_BASED)
54 #undef index
55 #undef rindex
56 #endif
57
58 _Tt_string_map::
59 _Tt_string_map (_Tt_object_table_keyfn key_function)
60 {
61         mapEntries = new _Tt_map_entry_table(key_function);
62 }
63
64 _Tt_string_map::
65 _Tt_string_map ()
66 {
67         mapEntries = new _Tt_map_entry_table((_Tt_object_table_keyfn)
68                                              &_Tt_map_entry::getAddress);
69 }
70
71 _Tt_string_map::
72 ~_Tt_string_map()
73 {
74 }
75
76 void _Tt_string_map::
77 loadFile (const _Tt_string &file)
78 {
79         const int   MAX_BUFFER_LEN = 1023;
80         const char *SEPARATORS = " \t";
81
82         mapEntries->flush();
83
84         FILE *fp = fopen(file, "r");
85
86         if (fp) {
87           
88                 _Tt_string buffer(MAX_BUFFER_LEN);
89
90                 bool_t throw_away = FALSE;
91
92                 fcntl(fileno(fp), F_SETFD, 1);  /* Close on exec */
93
94                 while (fgets(buffer, MAX_BUFFER_LEN+1, fp)) {
95                         int new_line_index = buffer.index('\n');
96
97                         // Throw away the characters read because no
98                         // new-line was found in the last buffer and
99                         // we only handle the first 1023 characters in a line
100                         if (throw_away) {
101                                 // If there is a new-line, then keep the
102                                 // next buffer
103                                 if (new_line_index > -1) {
104                                         throw_away = FALSE;
105                                 }
106                                 continue;
107                         }
108
109                         // If the current buffer has no new-line in it,
110                         // remember to throw away the next buffer
111                         if (new_line_index == -1) {
112                                 throw_away = TRUE;
113                         }
114                         else {
115                                 buffer [new_line_index] = '\0';
116                         }
117
118                         _Xstrtokparams strtok_buf;
119                         memset((char*) &strtok_buf, 0, sizeof(_Xstrtokparams));
120
121                         char *address_token = 
122                           _XStrtok(buffer, SEPARATORS, strtok_buf);
123                         if (address_token) {
124                                 // Make sure this is not a comment line
125                                 if (*address_token == '#') {
126                                         continue;
127                                 }
128
129                                 char *data_token = 
130                                   _XStrtok(NULL, SEPARATORS, strtok_buf);
131                                 if (data_token) {
132                                         _Tt_map_entry_ptr entry = new _Tt_map_entry;
133                                         entry->address = address_token;
134                                         entry->data = data_token;
135                                         mapEntries->insert(entry);
136                                 }
137                         }
138                 }
139                 
140                 (void)fclose(fp);
141         }
142         return;
143 }
144   
145 _Tt_string _Tt_string_map::findEntry(const _Tt_string &address)
146 {
147         _Tt_map_entry_table_ptr repeat_reference_map =
148           new _Tt_map_entry_table((_Tt_object_table_keyfn)
149                                   &_Tt_map_entry::getAddress);
150
151         _Tt_map_entry_ptr repeat_entry;
152         _Tt_map_entry_ptr current_entry = new _Tt_map_entry;
153         _Tt_map_entry_ptr next_entry = mapEntries->lookup(address);
154
155         // Chain the references to the entries in the map
156         while (!next_entry.is_null()) {
157                 repeat_reference_map->insert(next_entry);
158
159                 current_entry = next_entry;
160                 next_entry = mapEntries->lookup(current_entry->data);
161
162                 if (!next_entry.is_null()) {
163                         // Check if we have seen this entry before. If we
164                         // have, then we have a reference loop in the table,
165                         // so return a NULL string...
166                         repeat_entry
167                           = repeat_reference_map->lookup(next_entry->address);
168                         if (!repeat_entry.is_null()) {
169                                 return _Tt_string((char *)NULL);
170                         }
171                 }
172         }
173         return current_entry->data;
174 }