OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
shash.c
Go to the documentation of this file.
1 
2 #include <shash.h>
3 
4 #include <check.h>
5 #include <stdbool.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 
12 START_TEST(set_1){
13  shash *p1 = shash_create(0);
14  char k1[] = "key1";
15  char k2[] = "key2";
16  char v1_in[] = "value1";
17  char v1_2_in[] = "value1.2";
18  char v2_in[] = "value2";
19  char v2_const_in[] = "value3";
20 
21  ck_assert(shash_set(p1, k1, v1_in) == 0);
22  const char *v1_out = shash_get(p1, k1);
23  ck_assert_str_eq(v1_in, v1_out);
24 
25  ck_assert(shash_set(p1, k1, v1_2_in) == 1);
26  const char *v1_2_out = shash_get(p1, k1);
27  ck_assert_str_eq(v1_2_in, v1_2_out);
28 
29  ck_assert(shash_set(p1, k2, v2_in) == 0);
30  const char *v2_out = shash_get(p1, k2);
31  ck_assert_str_eq(v2_in, v2_out);
32 
33  ck_assert(shash_set(p1, "key2", v2_const_in) == 1);
34  const char *v2_const_out = shash_get(p1, "key2");
35  ck_assert_str_eq(v2_const_in, v2_const_out);
37 }
38 END_TEST
39 
40 START_TEST(get_out_of_scope){
41  shash *p1 = shash_create(0);
42  const char *v2_const_out = shash_get(p1, "key2");
43  ck_assert(v2_const_out == NULL);
45 }
46 END_TEST
47 
48 START_TEST(set_out_of_scope){
49  shash *p1 = shash_create(0);
50  int ret;
51  ret = shash_set(p1, "key2", "value3");
52  ck_assert(ret == 0);
53  ck_assert_str_eq(shash_get(p1, "key2"), "value3");
55 }
56 END_TEST
57 
58 START_TEST(iterating){
59  shash *p1 = shash_create(0);
60  int key_count;
61  char *keys[] = {"key1", "key2", "key3"};
62  char *values[] = {"value1", "value2", "value3"};
63 
64  for (key_count = 0; key_count < 3; key_count++){
65  ck_assert(shash_set(p1, keys[key_count], values[key_count]) == 0);
66  }
67 
68  int replace_value = 0;
69  for (replace_value = 0; replace_value < 2; replace_value++){
70  const char *key;
71  const char *value;
72  int rewind_count = 0;
73  for (rewind_count = 0; rewind_count < 3; rewind_count++){
74  key = value = NULL;
75  int found[key_count];
76  int k;
77  for (k=0;k<key_count;k++){
78  found[k] = 0;
79  }
80 
81 // shash_rewind(p1); //auto-rewind
82  while (!shash_next(p1, &key, &value)){
83  ck_assert(key != NULL && value != NULL);
84  for (k=0;k<key_count;k++){
85  if (!strcmp(keys[k], key) && !strcmp(values[k], value)){
86  found[k]++;
87  }
88  }
89  }
90 
91  for (k=0;k<key_count;k++){
92  ck_assert_int_eq(found[k], 1);
93  }
94  }
95  values[0] = "value4";
96  ck_assert_int_eq(shash_set(p1, keys[0], values[0]), 1);
97  }
99 }
100 END_TEST
101 
102 START_TEST(iterating_one_value){
103  shash *p1 = shash_create(0);
104  int key_count;
105  char *keys[] = {"key1"};
106  char *values[] = {"value1"};
107 
108  for (key_count = 0; key_count < 1; key_count++){
109  ck_assert(shash_set(p1, keys[key_count], values[key_count]) == 0);
110  }
111 
112  int replace_value = 0;
113  for (replace_value = 0; replace_value < 2; replace_value++){
114  const char *key;
115  const char *value;
116  int rewind_count = 0;
117  for (rewind_count = 0; rewind_count < 3; rewind_count++){
118  key = value = NULL;
119  int found[key_count];
120  int k;
121  for (k=0;k<key_count;k++){
122  found[k] = 0;
123  }
124 
125  shash_rewind(p1);
126  while (!shash_next(p1, &key, &value)){
127  ck_assert(key != NULL && value != NULL);
128  for (k=0;k<key_count;k++){
129  if (!strcmp(keys[k], key) && !strcmp(values[k], value)){
130  found[k]++;
131  }
132  }
133  }
134 
135  for (k=0;k<key_count;k++){
136  ck_assert_int_eq(found[k], 1);
137  }
138  }
139  values[0] = "value4";
140  ck_assert_int_eq(shash_set(p1, keys[0], values[0]), 1);
141  }
142  shash_destroy(p1);
143 }
144 END_TEST
145 
146 START_TEST(remove_1){
147  shash *p1 = shash_create(0);
148  int key_count;
149  char *keys[] = {"key1", "key2", "key3"};
150  char *values[] = {"value1", "value2", "value3"};
151 
152  for (key_count = 0; key_count < 3; key_count++){
153  ck_assert_int_eq(shash_set(p1, keys[key_count], values[key_count]), 0);
154  }
155 
156  int remove_value = 0;
157  for (remove_value = 0; remove_value < key_count-1; remove_value++){
158  const char *key;
159  const char *value;
160  key = value = NULL;
161  int found[key_count];
162  int k;
163  for (k=0;k<key_count;k++){
164  found[k] = 0;
165  }
166 
167  shash_rewind(p1);
168  while (!shash_next(p1, &key, &value)){
169  ck_assert(key != NULL && value != NULL);
170  for (k=0;k<key_count;k++){
171  if (!strcmp(keys[k], key) && !strcmp(values[k], value)){
172  found[k]++;
173  }
174  }
175  }
176  k = remove_value;
177  for (;k<key_count;k++){
178  ck_assert_int_eq(found[k], 1);
179  }
180  ck_assert_int_eq(shash_remove(p1, keys[remove_value]), 0);
181  }
182  ck_assert_ptr_eq(shash_get(p1, keys[remove_value-1]), NULL);
183  ck_assert_ptr_ne(shash_get(p1, keys[remove_value]), NULL);
184  shash_destroy(p1);
185 }
186 END_TEST
187 
188 static const char characters[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
189 static void random_string(char *buffer, int length){
190  int i=0;
191  for (i=0;i<length;i++){
192  buffer[i] = characters[rand() % (sizeof(characters)-1)];
193  }
194 }
195 
196 START_TEST(stress_test){
197  shash *p1 = shash_create(0);
198  int i, j, contains_dupes, count = 1000, length = 8;
199  char keys[count][length+1];
200  char values[count][length+1];
201 
202  for (i=0;i<count;i++){
203  random_string(keys[i], length);
204  random_string(values[i], length);
205  keys[i][length] = '\0';
206  values[i][length] = '\0';
207  }
208  do {
209  contains_dupes = 0;
210  for (i=0;i<count;i++){
211  for (j=i+1;j<count;j++){
212  if (!strcmp(keys[i], keys[j])){
213  contains_dupes = 1;
214  random_string(keys[j], length);
215  }
216  }
217  }
218  } while (contains_dupes);
219 
220  for (i=0;i<count;i++){
221  ck_assert_int_eq(shash_set(p1, keys[i], values[i]), 0);
222  }
223 
224  for (i=0;i<count;i++){
225  ck_assert_str_eq(values[i], shash_get(p1, keys[i]));
226  }
227  shash_destroy(p1);
228 }
229 END_TEST
230 
231 Suite* stub_suite(void){
232  Suite *s = suite_create("Stub");
233 
234  TCase *tc_core = tcase_create("Core");
235  tcase_add_test(tc_core, set_1);
236  tcase_add_test(tc_core, remove_1);
237  tcase_add_test(tc_core, iterating);
238  tcase_add_test(tc_core, iterating_one_value);
239  tcase_add_test(tc_core, stress_test);
240  suite_add_tcase(s, tc_core);
241 
242  TCase *tc_segfaults = tcase_create("Segfaults");
243  tcase_add_test(tc_segfaults, set_1);
244  tcase_add_test(tc_segfaults, get_out_of_scope);
245  tcase_add_test(tc_segfaults, set_out_of_scope);
246  suite_add_tcase(s, tc_segfaults);
247 
248  return s;
249 }
250 
251 int main(int argc, char **argv){
252  int number_failed;
253 
254  Suite *s = stub_suite();
255  SRunner *sr = srunner_create(s);
256 
257  srunner_run_all(sr, CK_VERBOSE);
258  number_failed = srunner_ntests_failed(sr);
259  srunner_free(sr);
260  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
261 }
int32 value
Definition: Granule.c:1235
START_TEST(set_1)
Definition: shash.c:12
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
int j
Definition: decode_rs.h:73
#define NULL
Definition: decode_rs.h:63
shash * shash_create(uint32_t options)
Initialize a shash object.
Definition: shash.c:105
int shash_set(shash *h, const char *key, const char *value)
Add or overwrite a pointer, associating it with the given key.
Definition: shash.c:224
Implementation-specific, generic type to store the shash object.
Definition: shash.c:40
END_TEST Suite * stub_suite(void)
Definition: shash.c:231
const char * shash_get(shash *h, const char *key)
Find a pointer associated with the given string.
Definition: shash.c:205
int shash_next(shash *h, const char **key, const char **value)
Retrieves the next key-value pair in the shash. The order in which the pointers are returned shall be...
Definition: shash.c:283
int shash_rewind(shash *h)
Rewind iterator for traversing all the keys and values.
Definition: shash.c:277
HISTORY txt for MOD_PR01(step one of PGE01) History follows the following convention needed due to new Aqua ReprocessingActual and the expected LUT revision number from PCF Changed to use PGE version for ProductionHistory Added Archive including ProcessingEnvironment Corrected handling of bad to resovle GSFcd02514 Changed to check staged LUT revision number versus the expected LUT revision number from thereby resolving defect report MODxl02056 This change also avoids the memory access violation reported in MODur00039 Changed the way output arrays were initialized with fill values
Definition: HISTORY.txt:162
A simple dictionary library for storing strings.
data_t s[NROOTS]
Definition: decode_rs.h:75
int main(int argc, char **argv)
Definition: shash.c:251
int shash_destroy(shash *h)
Destroy a shash object, free'ing the memory used.
Definition: shash.c:136
int shash_remove(shash *h, const char *key)
Remove a pointer associated with the given string.
Definition: shash.c:146
int i
Definition: decode_rs.h:71
int k
Definition: decode_rs.h:73
int count
Definition: decode_rs.h:79