1 /*
2  * test_encoding.cc: Part of GNU CSSC.
3  *
4  * Copyright (C) 1997, 1998, 2007, 2010, 2011, 2013, 2019 Free Software
5  * Foundation, Inc.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 #include <cstdio>
21 #include <cstddef>
22 #include <cstring>
23 #include <cstdlib>
24 
25 #include "bodyio.h"
26 
27 using encoding_impl::decode;
28 using encoding_impl::encode;
29 
30 int
test_encode(void)31 test_encode(void)
32 {
33   return encode_stream(stdin, stdout);
34 }
35 
36 int
test_decode(void)37 test_decode(void)
38 {
39   char inbuf[80], outbuf[80];
40   while ( 0 != fgets(inbuf, sizeof(inbuf)-1, stdin) )
41     {
42       int len = decode_line(inbuf, outbuf);
43       if (0 == len)
44 	return 0;
45       fwrite(outbuf, 1, len, stdout);
46     }
47   return 1;
48 }
49 
50 
51 // Test all possible inputs for encode(); decode its
52 // outputs and check that they decode back to the correct value.
test_all(void)53 int test_all(void)
54 {
55   union lunch { long l; char ch[4]; } in, out;
56   long i;
57 
58   // i only has to hlod a 24-bit value.
59   const long maxval = 0xff | (0xff<<8) | (0xff<<16);
60   const double dmaxval = maxval;
61   for (i=0; i<=maxval; i++)
62     {
63       if ( 0x7FFFF == (i & 0x7FFFF) )
64 	{
65 	  double completed = (100.0 * i) / dmaxval;
66 	  printf("%06lx %3.0f%%...\n", i, completed);
67 	}
68 
69 
70       in.ch[0] = (i & 0x0000ff) >>  0;
71       in.ch[1] = (i & 0x00ff00) >>  8;
72       in.ch[2] = (i & 0xff0000) >> 16;
73       in.ch[3] = '\0';
74 
75       encode(in.ch, out.ch);
76       decode(out.ch, in.ch);
77       const long l0 = ((unsigned char) in.ch[0]) & 0xff;
78       const long l1 = ((unsigned char) in.ch[1]) & 0xff;
79       const long l2 = ((unsigned char) in.ch[2]) & 0xff;
80       const long lo = l0 | l1<<8 | l2<<16;
81 
82       if (lo != i)
83 	{
84 	  fprintf(stderr,
85 		  "Asymmetry!\n"
86 		  "Input was %06lx, output was %05lx\n",
87 		  i, lo);
88 	  return 1;
89 	}
90     }
91   printf("Success!\n");
92   return 0;
93 }
94 
95 const char *options[] = { "--encode", "--decode", "--all" };
96 int (* const actions[])(void) = { test_encode, test_decode, test_all };
97 
98 #define NELEM(array)   (sizeof(array)/sizeof(array[0]))
99 
100 
101 static void
usage(const char * prog)102 usage(const char *prog)
103 {
104   fprintf(stderr, "Usage: %s [", prog);
105   for (size_t i=0; i<NELEM(options); ++i)
106     {
107       fprintf(stderr, "%s %s", (i>0) ? " |" : "", options[i]);
108     }
109   fprintf(stderr, " ]\n");
110 }
111 
112 int
main(int argc,char * argv[])113 main(int argc, char *argv[])
114 {
115   if (2 == argc)
116     {
117       for (size_t i=0; i<NELEM(options); ++i)
118 	if (0 == strcmp(options[i], argv[1]))
119 	  return (actions[i])();
120     }
121   else if (1 == argc)
122     {
123       // No options specified; the default is to perform the sanity test.
124       return test_all();
125     }
126   else
127     {
128       usage(argv[0] ? argv[0] : "encoding-test");
129     }
130   return 1;
131 }
132