]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/libcdl/testsuite/libcdl/cdl1.cxx
Initial revision
[karo-tx-redboot.git] / tools / src / libcdl / testsuite / libcdl / cdl1.cxx
1 //==========================================================================
2 //
3 //      cdl1.cxx
4 //
5 //      Basic testing of the CDL utility functions.                                                        
6 //
7 //==========================================================================
8 //####COPYRIGHTBEGIN####
9 //                                                                          
10 // ----------------------------------------------------------------------------
11 // Copyright (C) 1999, 2000 Red Hat, Inc.
12 //
13 // This file is part of the eCos host tools.
14 //
15 // This program is free software; you can redistribute it and/or modify it 
16 // under the terms of the GNU General Public License as published by the Free 
17 // Software Foundation; either version 2 of the License, or (at your option) 
18 // any later version.
19 // 
20 // This program is distributed in the hope that it will be useful, but WITHOUT 
21 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
22 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
23 // more details.
24 // 
25 // You should have received a copy of the GNU General Public License along with
26 // this program; if not, write to the Free Software Foundation, Inc., 
27 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28 //
29 // ----------------------------------------------------------------------------
30 //                                                                          
31 //####COPYRIGHTEND####
32 //==========================================================================
33 //#####DESCRIPTIONBEGIN####                                             
34 //
35 // Author(s):           bartv
36 // Contributors:        bartv
37 // Date:                1999-01-06
38 // Description:         There are a number of utility functions in the
39 //                      Cdl class to handle data validation, various
40 //                      conversions, etc.
41 //
42 //####DESCRIPTIONEND####
43 //==========================================================================
44
45 #include <cdlconfig.h>
46 #include <cdl.hxx>
47 #include <cyg/infra/cyg_ass.h>
48 #include <cyg/infra/cyg_trac.h>
49 #include <cyg/infra/testcase.h>
50 #include <cstdlib>
51 #include <cmath>
52
53 static bool
54 test_is_valid_property_id(void)
55 {
56     bool result = true;
57     CYG_REPORT_FUNCNAMETYPE("test_is_valid_property_id", "success %d");
58
59     if (!Cdl::is_valid_property_id(CdlPropertyId_ActiveIf)) {
60         CYG_TEST_FAIL("ActiveIf should be a valid property id");
61         result = false;
62     }
63     if (!Cdl::is_valid_property_id(CdlPropertyId_DefaultValue)) {
64         CYG_TEST_FAIL("DefaultValue should be a valid property id");
65         result = false;
66     }
67     if (!Cdl::is_valid_property_id(CdlPropertyId_Wizard)) {
68         CYG_TEST_FAIL("Wizard should be a valid property id");
69         result = false;
70     }
71     if (Cdl::is_valid_property_id(CdlPropertyId_Unknown)) {
72         CYG_TEST_FAIL("is_valid_property_id() accepted an invalid number");
73         result = false;
74     }
75     // This test could give spurious negatives in the very long term
76     union {
77         int           x;
78         CdlPropertyId id;
79     } dummy;
80     dummy.x = 1234;
81     if (Cdl::is_valid_property_id(dummy.id)) {
82         CYG_TEST_FAIL("is_valid_property_id() accepted an invalid number");
83         result = false;
84     }
85     
86     CYG_REPORT_RETVAL(result);
87     return result;
88 }
89
90 static bool
91 test_is_valid_property_class(void)
92 {
93     bool result = true;
94     CYG_REPORT_FUNCNAMETYPE("test_is_valid_property_class", "success %d");
95
96     if (!Cdl::is_valid_property_class(CdlPropertyClass_Minimal)) {
97         CYG_TEST_FAIL("Minimal should be a valid property class");
98         result = false;
99     }
100     if (!Cdl::is_valid_property_class(CdlPropertyClass_TclCode)) {
101         CYG_TEST_FAIL("TclCode should be a valid property class");
102         result = false;
103     }
104     if (!Cdl::is_valid_property_class(CdlPropertyClass_GoalExpression)) {
105         CYG_TEST_FAIL("GoalExpression should be a valid property class");
106         result = false;
107     }
108     if (Cdl::is_valid_property_class(CdlPropertyClass_Unknown)) {
109         CYG_TEST_FAIL("is_valid_property_class() accepted an invalid number");
110         result = false;
111     }
112     // This test could give spurious negatives in the very long term
113     union {
114         int                     x;
115         CdlPropertyClass        id;
116     } dummy;
117     dummy.x = 1234;
118     if (Cdl::is_valid_property_class(dummy.id)) {
119         CYG_TEST_FAIL("is_valid_property_class() accepted an invalid number");
120         result = false;
121     }
122     
123     CYG_REPORT_RETVAL(result);
124     return result;
125 }
126
127 static bool
128 test_is_valid_object_type(void)
129 {
130     bool result = true;
131     CYG_REPORT_FUNCNAMETYPE("test_is_valid_object_type", "success %d");
132
133     if (!Cdl::is_valid_object_type(CdlObjectType_Package)) {
134         CYG_TEST_FAIL("Package should be a valid object type");
135         result = false;
136     }
137     if (!Cdl::is_valid_object_type(CdlObjectType_Component)) {
138         CYG_TEST_FAIL("Component should be a valid object type");
139         result = false;
140     }
141     if (!Cdl::is_valid_object_type(CdlObjectType_Option)) {
142         CYG_TEST_FAIL("Option should be a valid object type");
143         result = false;
144     }
145     if (Cdl::is_valid_object_type(CdlObjectType_Unknown)) {
146         CYG_TEST_FAIL("is_valid_object_type() accepted an invalid number");
147         result = false;
148     }
149     // This test could give spurious negatives in the very long term
150     union {
151         int             x;
152         CdlObjectType   id;
153     } dummy;
154     dummy.x = 1234;
155     if (Cdl::is_valid_object_type(dummy.id)) {
156         CYG_TEST_FAIL("is_valid_object_type() accepted an invalid number");
157         result = false;
158     }
159     CYG_REPORT_RETVAL(result);
160     return result;
161 }
162
163 static bool
164 test_is_valid_option_flavor(void)
165 {
166     bool result = true;
167     CYG_REPORT_FUNCNAMETYPE("test_is_valid_option_flavor", "success %d");
168
169     if (!Cdl::is_valid_option_flavor(CdlOptionFlavor_Bool)) {
170         CYG_TEST_FAIL("Bool should be a valid option flavor");
171         result = false;
172     }
173     if (!Cdl::is_valid_option_flavor(CdlOptionFlavor_Enum)) {
174         CYG_TEST_FAIL("Enum should be a valid option flavor");
175         result = false;
176     }
177     if (!Cdl::is_valid_option_flavor(CdlOptionFlavor_Count)) {
178         CYG_TEST_FAIL("Count should be a valid option flavor");
179         result = false;
180     }
181     if (Cdl::is_valid_option_flavor(CdlOptionFlavor_Unknown)) {
182         CYG_TEST_FAIL("is_valid_option_flavor() accepted an invalid number");
183         result = false;
184     }
185     // This test could give spurious negatives in the very long term
186     union {
187         int             x;
188         CdlOptionFlavor id;
189     } dummy;
190     dummy.x = 1234;
191     if (Cdl::is_valid_option_flavor(dummy.id)) {
192         CYG_TEST_FAIL("is_valid_option_flavor() accepted an invalid number");
193         result = false;
194     }
195     CYG_REPORT_RETVAL(result);
196     return result;
197 }
198
199 static bool
200 test_is_valid_value_source(void)
201 {
202     bool result = true;
203     CYG_REPORT_FUNCNAMETYPE("test_is_valid_value_source", "success %d");
204
205     if (!Cdl::is_valid_value_source(CdlValueSource_Default)) {
206         CYG_TEST_FAIL("Default is a valid value source");
207         result = false;
208     }
209     if (!Cdl::is_valid_value_source(CdlValueSource_User)) {
210         CYG_TEST_FAIL("User is a valid value source");
211         result = false;
212     }
213     if (!Cdl::is_valid_value_source(CdlValueSource_Wizard)) {
214         CYG_TEST_FAIL("Wizard is a valid value source");
215         result = false;
216     }
217     if (!Cdl::is_valid_value_source(CdlValueSource_Inferred)) {
218         CYG_TEST_FAIL("Inferred is a valid value source");
219         result = false;
220     }
221     if (Cdl::is_valid_value_source(CdlValueSource_Unknown)) {
222         CYG_TEST_FAIL("is_valid_value_source() accepted an invalid number");
223         result = false;
224     }
225     // This test could give spurious negatives in the very long term
226     union {
227         int             x;
228         CdlValueSource  id;
229     } dummy;
230     dummy.x = 1234;
231     if (Cdl::is_valid_value_source(dummy.id)) {
232         CYG_TEST_FAIL("is_valid_value_source() accepted an invalid number");
233         result = false;
234     }
235     
236     CYG_REPORT_RETVAL(result);
237     return result;
238 }
239
240 static bool
241 test_string_to_integer(void)
242 {
243     bool result = true;
244     CYG_REPORT_FUNCNAMETYPE("test_string_to_integer", "success %d");
245
246     // Note that there is no robust way of specifying 64 bit constants.
247     // Some compilers will use a LL suffix, but not all. When a 64 bit
248     // constant is needed this has to be achieved using arithmetic,
249     // leaving the compiler to do the hard work.
250     //
251     // Compiler bogosity: VC++ does not appear the more normal way
252     // of initializing an array of structures using nested braces.
253     struct conversion_data {
254         bool            ok;
255         const char*     source;
256         cdl_int         expected;
257     } data[] = {
258         {  true,          "0",            0 },
259         {  true,          "1",            1 },
260         {  true,         "-1",           -1  },
261         {  true,        "0x0",            0  },
262         {  true,        "0x1",            1  },
263         {  true,         "01",            1  },
264         {  true,       "1234",         1234  },
265         {  true,      "-4567",        -4567  },
266         {  true, "2147483647",   2147483647  },
267         {  true,"-2147483648",  ((cdl_int) -2147483647) - 1  },
268         {  true, "0x7fffffff",   2147483647  },
269         {  true,"-0x80000000",  ((cdl_int) -2147483647) -1  },
270         {  true, "0x12ABCDEF",    313249263  },
271         {  true, "12345678987654321", ((cdl_int) 111111111) * ((cdl_int) 111111111) },
272         { false,          "A",            0  },
273         { false,         "0A",            0  },
274         { false,      "1234*",            0  },
275         { false,   "finished",            0  }
276     };
277
278     for (int i = 0; 0 != strcmp("finished", data[i].source); i++) {
279         cdl_int     res;
280         std::string source = std::string(data[i].source);
281         if (data[i].ok) {
282             if (!Cdl::string_to_integer(source, res)) {
283                 std::string msg = "the string \"" + source + "\" was not converted";
284                 CYG_TEST_FAIL(msg.c_str());
285                 result = false;
286             } else if (res != data[i].expected) {
287                 std::string msg = "the string \"" + source + "\" was converted incorrectly";
288                 CYG_TEST_FAIL(msg.c_str());
289                 result = false;
290             }
291         } else {
292             if (Cdl::string_to_integer(source, res)) {
293                 std::string msg = "the string \"" + source + "\" is invalid but was still converted";
294                 CYG_TEST_FAIL(msg.c_str());
295                 result = false;
296             }
297         }
298     }
299     
300     CYG_REPORT_RETVAL(result);
301     return result;
302 }
303
304 static bool
305 test_integer_to_string(void)
306 {
307     bool result = true;
308     CYG_REPORT_FUNCNAMETYPE("test_integer_to_string", "success %d");
309     
310     // Note that there is no robust way of specifying 64 bit constants.
311     // Some compilers will use a LL suffix, but not all. When a 64 bit
312     // constant is needed this has to be achieved using arithmetic,
313     // leaving the compiler to do the hard work.
314     //
315     // Integer to string conversions cannot fail.
316     //
317     // Compiler bogosity: VC++ does not appear the more normal way
318     // of initializing an array of structures using nested braces.
319     struct conversion_data {
320         cdl_int         source;
321         const char*     expected;
322     } data[] = {
323         {                0,           "0"  },
324         {                1,           "1"  },
325         {               -1,          "-1"  },
326         {               10,          "10"  },
327         {             1234,        "1234"  },
328         {          -456789,     "-456789"  },
329         {       2147483647,  "2147483647"  },
330         { ((cdl_int) 111111111) * ((cdl_int) 111111111), "12345678987654321"  },
331         {      (cdl_int) 0, "finished"     }
332     };
333
334     for (int i = 0; 0 != strcmp("finished", data[i].expected); i++) {
335         std::string res;
336         if (!Cdl::integer_to_string(data[i].source, res)) {
337             std::string msg = "the integer \"" + std::string(data[i].expected) + "\" was not converted";
338             CYG_TEST_FAIL(msg.c_str());
339             result = false;
340         } else if (res != data[i].expected) {
341             std::string msg = "the string \"" + std::string(data[i].expected) + "\" was converted incorrectly";
342             CYG_TEST_FAIL(msg.c_str());
343             result = false;
344         }
345     }
346
347     // Just a few more tests. Try converting some sequences to a string and back
348     // again.
349     for (int j = 0; j < 4; j++) {
350         cdl_int starting_values[] = { 1, 3, -1, -2 };
351         cdl_int current_value     = starting_values[j];
352
353         for (int k = 0; k < 60; k++) {
354             current_value <<= 1;
355             cdl_int     int_tmp;
356             std::string str_tmp;
357             if (!Cdl::integer_to_string(current_value, str_tmp)) {
358                 CYG_TEST_FAIL("unable to convert valid integer to string");
359                 result = false;
360                 break;
361             }
362             if (!Cdl::string_to_integer(str_tmp, int_tmp)) {
363                 CYG_TEST_FAIL("unable to convert string back to integer");
364                 result = false;
365                 break;
366             }
367             if (current_value != int_tmp) {
368                 CYG_TEST_FAIL("integer conversion to/from strings not idempotent");
369                 result = false;
370                 break;
371             }
372         }
373     }
374     
375     CYG_REPORT_RETVAL(result);
376     return result;
377 }
378
379 static bool
380 test_string_to_bool(void)
381 {
382     bool result = true;
383     CYG_REPORT_FUNCNAMETYPE("test_string_to_bool", "success %d");
384
385     // Legal values for true  include 1 and "true".
386     // Legal values for false include 0 and "false".
387     // A random string should fail to convert.
388     bool res;
389     if (!Cdl::string_to_bool("1", res)) {
390         CYG_TEST_FAIL("the string \"1\" was not converted");
391         result = false;
392     } else if (res != true) {
393         CYG_TEST_FAIL("the string \"1\" did not convert to true");
394         result = false;
395     }
396     if (!Cdl::string_to_bool("true", res)) {
397         CYG_TEST_FAIL("the string \"true\" was not converted");
398         result = false;
399     } else if (res != true) {
400         CYG_TEST_FAIL("the string \"true\" did not convert to true");
401         result = false;
402     }
403     if (!Cdl::string_to_bool("0", res)) {
404         CYG_TEST_FAIL("the string \"0\" was not converted");
405         result = false;
406     } else if (res != false) {
407         CYG_TEST_FAIL("the string \"0\" did not convert to false");
408         result = false;
409     }
410     if (!Cdl::string_to_bool("false", res)) {
411         CYG_TEST_FAIL("the string \"false\" was not converted");
412         result = false;
413     } else if (res != false) {
414         CYG_TEST_FAIL("the string \"false\" did not convert to false");
415         result = false;
416     }
417     if (Cdl::string_to_bool("not a boolean string", res)) {
418         CYG_TEST_FAIL("a spurious string was converted to a boolean");
419         result = false;
420     }
421     
422     CYG_REPORT_RETVAL(result);
423     return result;
424 }
425
426 static bool
427 test_bool_to_string(void)
428 {
429     bool result = true;
430     CYG_REPORT_FUNCNAMETYPE("test_bool_to_string", "success %d");
431
432     std::string str;
433     if (!Cdl::bool_to_string(true, str)) {
434         CYG_TEST_FAIL("bool_to_string() failed for `true'");
435         result = false;
436     } else if ("1" != str) {
437         CYG_TEST_FAIL("boolean value true translated incorrectly");
438         result = false;
439     }
440     if (!Cdl::bool_to_string(false,str)) {
441         CYG_TEST_FAIL("bool_to_string() failed for `true'");
442         result = false;
443     } else if ("0" != str) {
444         CYG_TEST_FAIL("boolean value false translated incorrectly");
445         result = false;
446     }
447     // There is no easy way to test failure conditions. The trick
448     // of sticking a random number into a union will not work, there
449     // are absolutely no guarantees about the internal implementation
450     // of the bool data type in C++
451     
452     CYG_REPORT_RETVAL(result);
453     return result;
454 }
455
456 // This test is not intended to be comprehensive. In particular it is
457 // not very easy to validate the results, issues like locales get in the way.
458 static bool
459 test_double_to_string(void)
460 {
461     bool result = true;
462     CYG_REPORT_FUNCNAMETYPE("test_double_to_string", "success %d");
463
464     std::string str;
465     if (!Cdl::double_to_string(0.0, str)) {
466         CYG_TEST_FAIL("double_to_string() failed for 0.0");
467         result = false;
468     } else if (('0' != str[0]) && (('-' != str[0]) && ('0' != str[1]))) {
469         fprintf(stderr, "result of conversion is %s\n", str.c_str());
470         CYG_TEST_FAIL("double_to_string() returned strange result for 0.0");
471         result = false;
472     }
473     
474     if (!Cdl::double_to_string(3.141592, str)) {
475         CYG_TEST_FAIL("double_to_string() failed for pi");
476         result = false;
477     } else if (('3' != str[0]) || ('1' != str[2]) || ('4' != str[3]) || ('1' != str[4])) {
478         CYG_TEST_FAIL("double_to_string() returned strange result for pi");
479         result = false;
480     }
481
482     if (!Cdl::double_to_string(-1.23456789E15, str)) {
483         CYG_TEST_FAIL("double_to_string() failed for large but legal value");
484         result = false;
485     } else if (('-' != str[0]) && ('1' != str[1]) && (10 >= str.size())) {
486         CYG_TEST_FAIL("double_to_string() returned strange result for large but legal value");
487         result = false;
488     }
489
490     CYG_REPORT_RETVAL(result);
491     return result;
492 }
493
494 // This test is not intended to be comprehensive.
495 static bool
496 test_string_to_double(void)
497 {
498     bool result = true;
499     CYG_REPORT_FUNCNAMETYPE("test_string_to_double", "success %d");
500
501     double val;
502     if (!Cdl::string_to_double("0.0", val)) {
503         CYG_TEST_FAIL("string_to_double() failed for 0.0");
504         result = false;
505     } else if (fabs(val) > 0.000001) {
506         CYG_TEST_FAIL("string_to_double() produced strange result for 0.0");
507         result = false;
508     }
509     if (!Cdl::string_to_double("3.141592", val)) {
510         CYG_TEST_FAIL("string_to_double() failed for pi");
511         result = false;
512     } else if (fabs(val - 3.141592) > 0.000001) {
513         CYG_TEST_FAIL("string_to_double() produced strange result for pi");
514         result = false;
515     }
516     if (!Cdl::string_to_double("-1.23456789E15", val)) {
517         CYG_TEST_FAIL("string_to_double() failed for large but legal value");
518         result = false;
519     } else if (fabs(val - -1.23456789E15) > 0.000001) {
520         CYG_TEST_FAIL("string_to_double() produced strange result for large but legal value");
521         result = false;
522     }
523     if (Cdl::string_to_double("random junk", val)) {
524         CYG_TEST_FAIL("string_to_double() succeeded for junk data");
525         result = false;
526     }
527     if (Cdl::string_to_double("1.23456789E1234", val)) {
528         CYG_TEST_FAIL("string_to_double() succeeded for impossibly large value");
529         result = false;
530     }
531     if (Cdl::string_to_double("1.0 and then some", val)) {
532         CYG_TEST_FAIL("string_to_double() succeeded for number followed by junk");
533         result = false;
534     }
535     
536     CYG_REPORT_RETVAL(result);
537     return result;
538 }
539
540 int
541 main(int argc, char** argv)
542 {
543     CYG_REPORT_FUNCNAMETYPE("main", "result %d");
544     
545     if (test_is_valid_property_id()) {
546         CYG_TEST_PASS("is_valid_property_id()");
547     }
548     if (test_is_valid_property_class()) {
549         CYG_TEST_PASS("is_valid_property_class()");
550     }
551     if (test_is_valid_object_type()) {
552         CYG_TEST_PASS("is_valid_object_type()");
553     }
554     if (test_is_valid_option_flavor()) {
555         CYG_TEST_PASS("is_valid_option_flavor");
556     }
557     if (test_is_valid_value_source()) {
558         CYG_TEST_PASS("is_valid_value_source");
559     }
560     if (test_string_to_integer()) {
561         CYG_TEST_PASS("string_to_integer");
562     }
563     if (test_string_to_bool()) {
564         CYG_TEST_PASS("string to bool");
565     }
566     if (test_integer_to_string()) {
567         CYG_TEST_PASS("integer_to_string");
568     }
569     if (test_bool_to_string()) {
570         CYG_TEST_PASS("bool_to_string");
571     }
572     if (test_string_to_double()) {
573         CYG_TEST_PASS("string_to_double");
574     }
575     if (test_double_to_string()) {
576         CYG_TEST_PASS("double_to_string");
577     }
578     
579     CYG_REPORT_RETVAL(EXIT_SUCCESS);
580     return EXIT_SUCCESS;
581 }
582