1 /**
2   @file
3 
4   @ingroup mtr
5 
6   @brief Test program for the mtr package.
7 
8   @author Fabio Somenzi
9 
10   @copyright@parblock
11   Copyright (c) 1995-2015, Regents of the University of Colorado
12 
13   All rights reserved.
14 
15   Redistribution and use in source and binary forms, with or without
16   modification, are permitted provided that the following conditions
17   are met:
18 
19   Redistributions of source code must retain the above copyright
20   notice, this list of conditions and the following disclaimer.
21 
22   Redistributions in binary form must reproduce the above copyright
23   notice, this list of conditions and the following disclaimer in the
24   documentation and/or other materials provided with the distribution.
25 
26   Neither the name of the University of Colorado nor the names of its
27   contributors may be used to endorse or promote products derived from
28   this software without specific prior written permission.
29 
30   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41   POSSIBILITY OF SUCH DAMAGE.
42   @endparblock
43 
44 */
45 
46 #include "util.h"
47 #include "mtrInt.h"
48 
49 /*---------------------------------------------------------------------------*/
50 /* Variable declarations                                                     */
51 /*---------------------------------------------------------------------------*/
52 
53 #ifndef lint
54 static char rcsid[] MTR_UNUSED = "$Id: testmtr.c,v 1.8 2015/07/01 20:43:45 fabio Exp $";
55 #endif
56 
57 /*---------------------------------------------------------------------------*/
58 /* Constant declarations                                                     */
59 /*---------------------------------------------------------------------------*/
60 
61 #define TESTMTR_VERSION\
62     "TestMtr Version #0.6, Release date 2/6/12"
63 
64 /** \cond */
65 
66 
67 /*---------------------------------------------------------------------------*/
68 /* Static function prototypes                                                */
69 /*---------------------------------------------------------------------------*/
70 
71 static void usage (char *prog);
72 static FILE * open_file (const char *filename, const char *mode);
73 static void printHeader(int argc, char **argv);
74 
75 /** \endcond */
76 
77 
78 /*---------------------------------------------------------------------------*/
79 /* Definition of exported functions                                          */
80 /*---------------------------------------------------------------------------*/
81 
82 /**
83   @brief Main program for testmtr.
84 
85   @details Performs initialization.  Reads command line options and
86   network(s).  Builds some simple trees and prints them out.
87 
88   @sideeffect None
89 
90 */
91 int
main(int argc,char ** argv)92 main(
93   int  argc,
94   char ** argv)
95 {
96     MtrNode *root,
97 	    *node;
98     int	    i,
99 	    pr = 0;
100     FILE    *fp;
101     const char *file = NULL;
102 
103     for (i = 1; i < argc; i++) {
104       if (strcmp("-M", argv[i]) == 0) {
105         continue;
106       } else if (strcmp("-p", argv[i]) == 0) {
107         pr = atoi(argv[++i]);
108       } else if (strcmp("-h", argv[i]) == 0) {
109         printHeader(argc, argv);
110         usage(argv[0]);
111       } else if (i == argc - 1) {
112         file = argv[i];
113       } else {
114         printHeader(argc, argv);
115         usage(argv[0]);
116       }
117     }
118     if (file == NULL) {
119       file = "-";
120     }
121     if (pr > 0)
122         printHeader(argc, argv);
123 
124     /* Create and print a simple tree. */
125     root = Mtr_InitTree();
126     root->flags = 0;
127     node = Mtr_CreateFirstChild(root);
128     node->flags = 1;
129     node = Mtr_CreateLastChild(root);
130     node->flags = 2;
131     node = Mtr_CreateFirstChild(root);
132     node->flags = 3;
133     node = Mtr_AllocNode();
134     node->child = NULL;
135     node->flags = 4;
136     Mtr_MakeNextSibling(root->child,node);
137     if (pr > 0) {
138         Mtr_PrintTree(root);
139         (void) printf("#------------------------\n");
140     }
141     Mtr_FreeTree(root);
142 
143     /* Create an initial tree in which all variables belong to one group. */
144     root = Mtr_InitGroupTree(0,12);
145     if (pr > 0) {
146         Mtr_PrintTree(root); (void) printf("#  ");
147         Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
148     }
149     (void) Mtr_MakeGroup(root,0,6,MTR_DEFAULT);
150     (void) Mtr_MakeGroup(root,6,6,MTR_DEFAULT);
151     if (pr > 0) {
152         Mtr_PrintTree(root); (void) printf("#  ");
153         Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
154     }
155     for (i = 0; i < 6; i+=2) {
156       (void) Mtr_MakeGroup(root,(unsigned) i,(unsigned) 2,MTR_DEFAULT);
157     }
158     (void) Mtr_MakeGroup(root,0,12,MTR_FIXED);
159     if (pr > 0) {
160         Mtr_PrintTree(root); (void) printf("#  ");
161         Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
162         /* Print a partial tree. */
163         (void) printf("#  ");
164         Mtr_PrintGroups(root->child,pr == 0); (void) printf("\n");
165     }
166     node = Mtr_FindGroup(root,0,6);
167     (void) Mtr_DissolveGroup(node);
168     if (pr > 0) {
169         Mtr_PrintTree(root); (void) printf("#  ");
170         Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
171     }
172     node = Mtr_FindGroup(root,4,2);
173     if (!Mtr_SwapGroups(node,node->younger)) {
174 	(void) printf("error in Mtr_SwapGroups\n");
175 	return 3;
176     }
177     if (pr > 0) {
178         Mtr_PrintTree(root); (void) printf("#  ");
179         Mtr_PrintGroups(root,pr == 0);
180         (void) printf("#------------------------\n");
181     }
182     Mtr_FreeTree(root);
183 
184     /* Create a group tree with fixed subgroups. */
185     root = Mtr_InitGroupTree(0,4);
186     if (pr > 0) {
187         Mtr_PrintTree(root); (void) printf("#  ");
188         Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
189     }
190     (void) Mtr_MakeGroup(root,0,2,MTR_FIXED);
191     (void) Mtr_MakeGroup(root,2,2,MTR_FIXED);
192     if (pr > 0) {
193         Mtr_PrintTree(root); (void) printf("#  ");
194         Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
195     }
196     Mtr_FreeTree(root);
197     if (pr > 0) {
198         (void) printf("#------------------------\n");
199     }
200 
201     /* Open input file. */
202     fp = open_file(file, "r");
203     root = Mtr_ReadGroups(fp,12);
204     fclose(fp);
205     if (pr > 0) {
206         if (root) {
207             Mtr_PrintTree(root); (void) printf("#  ");
208             Mtr_PrintGroups(root,pr == 0); (void) printf("\n");
209         } else {
210             (void) printf("error in group file\n");
211         }
212     }
213     Mtr_FreeTree(root);
214 
215     return 0;
216 
217 } /* end of main */
218 
219 
220 /**
221   @brief Prints usage message and exits.
222 
223   @sideeffect none
224 
225 */
226 static void
usage(char * prog)227 usage(
228   char * prog)
229 {
230     (void) fprintf(stderr, "usage: %s [options] [file]\n", prog);
231     (void) fprintf(stderr, "   -M\t\tturns off memory allocation recording\n");
232     (void) fprintf(stderr, "   -h\t\tprints this message\n");
233     (void) fprintf(stderr, "   -p n\t\tcontrols verbosity\n");
234     exit(2);
235 
236 } /* end of usage */
237 
238 
239 /**
240   @brief Opens a file.
241 
242   @details Opens a file, or fails with an error message and exits.
243   Allows '-' as a synonym for standard input.
244 
245   @sideeffect None
246 
247 */
248 static FILE *
open_file(const char * filename,const char * mode)249 open_file(
250   const char * filename,
251   const char * mode)
252 {
253     FILE *fp;
254 
255     if (strcmp(filename, "-") == 0) {
256         return mode[0] == 'r' ? stdin : stdout;
257     } else if ((fp = fopen(filename, mode)) == NULL) {
258         perror(filename);
259         exit(1);
260     }
261     return(fp);
262 
263 } /* end of open_file */
264 
265 
266 /**
267   @brief Prints the header of the program output.
268 
269   @sideeffect None
270 
271 */
272 static void
printHeader(int argc,char ** argv)273 printHeader(
274   int argc,
275   char **argv)
276 {
277     int i;
278 
279     (void) printf("# %s\n", TESTMTR_VERSION);
280     /* Echo command line and arguments. */
281     (void) printf("#");
282     for(i = 0; i < argc; i++) {
283 	(void) printf(" %s", argv[i]);
284     }
285     (void) printf("\n");
286     (void) fflush(stdout);
287 }
288