1 //
2 // ipv2_karray.cc
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 /* These routines manipulate keyword arrays. A keyword
29 * array differs from a data array in that its indices are indicated
30 * by a keyword segment. For example: array:0:1 = 6 is a keyword
31 * array element. The count is the upper bound plus 1. */
32
33 /* NOTE: If these routines are used to access keyword arrays, then
34 * only the first place in the cwk in which a keyword array name is
35 * found will be used. */
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <stdarg.h>
40 #include <string.h>
41 #include <util/keyval/ipv2.h>
42
43 using namespace sc;
44
45 void
ip_cwk_karray_add_v(int n,int * v)46 IPV2::ip_cwk_karray_add_v(int n,int*v)
47 {
48 int i;
49 char indices[110],index[10];
50
51 if (n>10) {
52 warn("ip_cwk_karray_add_v: too many indices");
53 return;
54 }
55 indices[0] = '\0';
56 for (i=0; i<n; i++) {
57 if (v[i] > 999999999 || v[i] < 0) {
58 warn("ip_cwk_karray_add_v: an index is too large or small");
59 return;
60 }
61 sprintf(index,"%d",v[i]);
62 strcpy(indices,index);
63 if (i!=n-1) strcpy(indices,":");
64 }
65 cwk_add(indices);
66 return;
67 }
68
69 void
ip_cwk_karray_add(int n,...)70 IPV2::ip_cwk_karray_add(int n,...)
71 {
72 va_list args;
73 int i;
74 int *v;
75
76 if (n==0) {
77 ip_cwk_karray_add_v(n,NULL);
78 return;
79 }
80 else {
81 v = (int *) malloc(sizeof(int)*n);
82 if (!v) {
83 warn("ip_cwk_karray_add: problem with malloc");
84 return;
85 }
86 va_start(args, n);
87 for (i=0; i<n; i++) {
88 v[i] = va_arg(args,int);
89 }
90 va_end(args);
91 free(v);
92 ip_cwk_karray_add_v(n,v);
93 return;
94 }
95 }
96
97 ip_keyword_tree_t*
ip_karray_descend_v(ip_keyword_tree_t * kt,int n,int * v)98 IPV2::ip_karray_descend_v(ip_keyword_tree_t*kt,int n,int*v)
99 {
100 ip_keyword_tree_t *r;
101 int i;
102 char index[10];
103
104 if (!kt) return NULL;
105
106 /* kt starts off at the array so we must first descend to the first
107 * level of indices. */
108 r = kt->down;
109 if (!r) return NULL;
110
111 for (i=0; i<n; i++) {
112 if (!r) return r;
113 if (v[i] > 999999999 || v[i] < 0) {
114 warn("ip_karray_descend_v: an index is too large or small");
115 return NULL;
116 }
117 sprintf(index,"%d",v[i]);
118 r = ip_descend_tree(r,index);
119 if (r) r=r->down;
120 }
121 return r;
122 }
123
124 ip_keyword_tree_t*
ip_karray_descend(ip_keyword_tree_t * kt,int n,...)125 IPV2::ip_karray_descend(ip_keyword_tree_t*kt,int n,...)
126 {
127 va_list args;
128 int i;
129 int *v;
130
131 if (n==0) {
132 return ip_karray_descend_v(kt,n,NULL);
133 }
134 else {
135 v = (int *) malloc(sizeof(int)*n);
136 if (!v) {
137 warn("ip_karray_descend: problem with malloc");
138 return NULL;
139 }
140 va_start(args, n);
141 for (i=0; i<n; i++) {
142 v[i] = va_arg(args,int);
143 }
144 va_end(args);
145 free(v);
146 return ip_karray_descend_v(kt,n,v);
147 }
148 }
149
150 IPV2::Status
count_v(const char * keyword,int * karray_count,int n,int * v)151 IPV2::count_v(const char* keyword,int*karray_count,int n,int*v)
152 {
153 ip_keyword_tree_t *kt,*I;
154 int index;
155 int max;
156
157 /* Descend the keyword tree to keyword. */
158 kt = ip_cwk_descend_tree(keyword);
159 if (kt == NULL) return KeyNotFound;
160
161 /* Descend the tree to the indices. */
162 kt = ip_karray_descend_v(kt,n,v);
163 if (kt == NULL) return NotAnArray;
164
165 /* Go thru the keyword array and examine the indices. */
166 I = kt;
167 max = 0;
168 do {
169 if (sscanf(I->keyword,"%d",&index) != 1) return OutOfBounds;
170 if (index<0) return OutOfBounds;
171 if (index+1 > max) max = index + 1;
172 } while ((I = I->across) != kt);
173
174 *karray_count = max;
175 return OK;
176 }
177
178 /* This counts the number of elements in a keyword array. */
179 IPV2::Status
count(const char * keyword,int * karray_count,int n,...)180 IPV2::count(const char *keyword,int *karray_count,int n,...)
181 {
182 va_list args;
183 int i;
184 int *v;
185 Status r;
186
187 if (n==0) {
188 return count_v(keyword,karray_count,n,NULL);
189 }
190 else {
191 v = (int *) malloc(sizeof(int)*n);
192 if (!v) return Malloc;
193 va_start(args, n);
194 for (i=0; i<n; i++) {
195 v[i] = va_arg(args,int);
196 }
197 va_end(args);
198 r = count_v(keyword,karray_count,n,v);
199 free(v);
200 return r;
201 }
202 }
203