Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / doc / util / dbtoman / instant / info.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: info.c /main/1 1996/07/23 19:42:57 rws $ */
24 /*
25  *  Copyright 1993 Open Software Foundation, Inc., Cambridge, Massachusetts.
26  *  All rights reserved.
27  */
28 /*
29  * Copyright (c) 1994  
30  * Open Software Foundation, Inc. 
31  *  
32  * Permission is hereby granted to use, copy, modify and freely distribute 
33  * the software in this file and its documentation for any purpose without 
34  * fee, provided that the above copyright notice appears in all copies and 
35  * that both the copyright notice and this permission notice appear in 
36  * supporting documentation.  Further, provided that the name of Open 
37  * Software Foundation, Inc. ("OSF") not be used in advertising or 
38  * publicity pertaining to distribution of the software without prior 
39  * written permission from OSF.  OSF makes no representations about the 
40  * suitability of this software for any purpose.  It is provided "as is" 
41  * without express or implied warranty. 
42  */
43 /*
44  * Copyright (c) 1996 X Consortium
45  * Copyright (c) 1995, 1996 Dalrymple Consulting
46  * 
47  * Permission is hereby granted, free of charge, to any person obtaining a copy
48  * of this software and associated documentation files (the "Software"), to deal
49  * in the Software without restriction, including without limitation the rights
50  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
51  * copies of the Software, and to permit persons to whom the Software is
52  * furnished to do so, subject to the following conditions:
53  * 
54  * The above copyright notice and this permission notice shall be included in
55  * all copies or substantial portions of the Software.
56  * 
57  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
58  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
59  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
60  * X CONSORTIUM OR DALRYMPLE CONSULTING BE LIABLE FOR ANY CLAIM, DAMAGES OR
61  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
62  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
63  * OTHER DEALINGS IN THE SOFTWARE.
64  * 
65  * Except as contained in this notice, the names of the X Consortium and
66  * Dalrymple Consulting shall not be used in advertising or otherwise to
67  * promote the sale, use or other dealings in this Software without prior
68  * written authorization.
69  */
70 /* ________________________________________________________________________
71  *
72  *  Functions for printing information about an instance in the 'instant'
73  *  program.  Most of these are fairly short and simple.
74  *
75  *  Entry points for this module:
76  *      PrintElemSummary(elem)  print summary info of each element
77  *      PrintContext(elem)      print context of each element
78  *      PrintElemTree(elem)     print tree of document
79  *      PrintStats(elem)        print statistics about doc tree
80  *      PrintIDList(elem)       print list of IDs and element context
81  *  Most Print*() functions start at subtree pointed to by 'elem'.
82  * ________________________________________________________________________
83  */
84
85 #include <stdio.h>
86 #include <stdlib.h>
87 #include <ctype.h>
88 #include <string.h>
89
90 #include "general.h"
91
92 /* ______________________________________________________________________ */
93 /*  Print a summary of each tag use in the instance.  Things like depth in
94  *  the tree, number of children, parent, attributes.
95  */
96
97 /*  Do the actual printing.  Print the info about the node.  If null,
98  *  print a header for the columns.
99  *  Arguments:
100  *      Pointer to element structure of the node to print.
101  */
102 static void
103 print_summ(
104     Element_t   *e
105 )
106 {
107     int i, n, dsize;
108     char *hfmt="%-18.18s %4s %5s %4s %4s %s\n";
109     char *fmt ="%-18.18s %4d %5d %4d %4d %s\n";
110
111     if (e == NULL) {
112         fprintf(outfp, hfmt, "Element", "Att", "Data", "Chd", "Dep", "Parent");
113         return;
114     }
115     for (i=0,n=0; i<e->ncont; i++) if (IsContElem(e,i)) n++;
116     for (i=0,dsize=0; i<e->ncont; i++)
117         if (IsContElem(e,i)) dsize += strlen(e->cont[i].ch.data);
118     fprintf(outfp, fmt, e->gi, e->natts, dsize, n, e->depth,
119         e->parent ? e->parent->gi : "-");
120
121     for (i=0; i<e->natts; i++) {
122         fprintf(outfp, "%45d: %s = %s\n", i, e->atts[i].name,
123             e->atts[i].sval ? e->atts[i].sval : "empty");
124     }
125 }
126
127 /*  Descend the tree, calling processing routine.
128  *  Arguments:
129  *      Pointer to element structure at top of tree to traverse.
130  */
131 void
132 PrintElemSummary(
133     Element_t   *e
134 )
135 {
136     print_summ(0);
137     DescendTree(e, print_summ, 0, 0, 0);
138 }
139
140 /* ______________________________________________________________________ */
141 /*  Print the context of each tag in the instance (i.e. the tag with its
142  *  ancestors).
143  */
144
145 /*  Do the actual printing.  Print the context of the node.
146  *  Arguments:
147  *      Pointer to element structure of the node to print.
148  */
149 static void
150 print_context(
151     Element_t   *e
152 )
153 {
154     char buf[LINESIZE];
155
156     fprintf(outfp, "%-22s %s\n", e->gi, FindContext(e, 10, buf));
157 }
158
159 /*  Descend the tree, calling processing routine.
160  *  Arguments:
161  *      Pointer to element structure at top of tree to traverse.
162  */
163 void
164 PrintContext(
165     Element_t   *e
166 )
167 {
168     fprintf(outfp, "%-22s %s\n", "Element", "Context");
169     fprintf(outfp, "%-22s %s\n", "---------------", "-----------");
170     DescendTree(e, print_context, 0, 0, 0);
171
172     putc(NL, outfp);
173 }
174
175 /* ______________________________________________________________________ */
176 /*  Print tree of the instance.  GI's are printed indented by their depth
177  *  in the tree.
178  */
179
180 /*  Do the actual printing.  Print the element name, indented the right amount.
181  *  Arguments:
182  *      Pointer to element structure of the node to print.
183  */
184 static void
185 print_indent(
186     Element_t   *e
187 )
188 {
189     int         i, ne, nd;
190     for(i=0; i<e->depth; i++) fputs(".  ", outfp);
191     for(i=0,ne=0; i<e->ncont; i++) if (IsContElem(e,i)) ne++;
192     for(i=0,nd=0; i<e->ncont; i++) if IsContData(e,i) nd++;
193     fprintf(outfp, "%s  (%d,%d)\n", e->gi, ne, nd);
194 }
195
196 /*  Descend the tree, calling processing routine.
197  *  Arguments:
198  *      Pointer to element structure at top of tree to traverse.
199  */
200 void
201 PrintElemTree(
202     Element_t   *e
203 )
204 {
205     DescendTree(e, print_indent, 0, 0, 0);
206     putc(NL, outfp);
207 }
208
209 /* ______________________________________________________________________ */
210 /*  Print some statistics about the instance.
211  */
212
213 /*  Accumulate the totals for the statistics.
214  *  Arguments:
215  *      Pointer to element structure of the node to print.
216  *      Pointer to the total number of elements.
217  *      Pointer to the total amount of content data.
218  *      Pointer to the maximum depth of tree.
219  */
220 static void
221 acc_tots(
222     Element_t   *e,
223     int         *tot_el,
224     int         *tot_data,
225     int         *max_depth
226 )
227 {
228     int         i;
229     for(i=0; i<e->necont; i++)
230         acc_tots(e->econt[i], tot_el, tot_data, max_depth);
231     for (i=0; i<e->necont; i++) (*tot_el)++;
232     for (i=0; i<e->ndcont; i++) (*tot_data) += strlen(e->dcont[i]);
233     if (e->depth > (*max_depth)) *max_depth = e->depth;
234 }
235
236 /*  Descend the tree (recursively), collecting the statistics.
237  *  Arguments:
238  *      Pointer to element structure of the node to print.
239  *      Pointer to the total number of elements.
240  *      Pointer to the total amount of content data.
241  *      Pointer to the maximum depth of tree.
242  */
243 static void
244 elem_usage(
245     Element_t   *e,
246     char        *name,
247     int         *n_used,
248     int         *nchars
249 )
250 {
251     int         i;
252     if (!strcmp(name, e->gi)) {
253         (*n_used)++;
254         for (i=0; i<e->ncont; i++)
255             if (IsContData(e,i)) (*nchars) += strlen(ContData(e,i));
256     }
257     for(i=0; i<e->necont; i++)
258         elem_usage(e->econt[i], name, n_used, nchars);
259 }
260
261 /*  Descend the tree, calling processing routine.
262  *  Arguments:
263  *      Pointer to element structure at top of tree to traverse.
264  */
265 void
266 PrintStats(
267     Element_t   *top
268 )
269 {
270     int         i, n;
271     int         dif_el=0, tot_el=0, tot_data=0, nchars, max_depth=0;
272     float       pct;
273
274     fprintf(outfp, "%-22s %s   %s\n", "Element name",    "Occurrances", "Character Content");
275     fprintf(outfp, "%-22s %s   %s\n", "---------------", "-----------", "-----------------");
276
277     acc_tots(top, &tot_el, &tot_data, &max_depth);
278
279     for (i=0; i<nUsedElem; i++) {
280         n = 0;
281         nchars = 0;
282         elem_usage(top, UsedElem[i], &n, &nchars);
283         if (n > 0) {
284             pct = 100.0 * (float)n / (float)tot_el;
285             fprintf(outfp, "%-22s %4d  %4.1f%%   %6d  %4d\n", UsedElem[i],
286                 n, pct, nchars, (nchars/n));
287             dif_el++;
288         }
289     }
290
291     fprintf(outfp, "\nTotal of %d elements used, %d different ones.\n",
292         tot_el, dif_el);
293     fprintf(outfp, "Total character data: %d.\n", tot_data);
294     fprintf(outfp, "Maximum element depth: %d.\n", max_depth);
295     putc(NL, outfp);
296 }
297
298 /* ______________________________________________________________________ */
299 /* Print list of: ID, GI, input file, line number, separated by colons.
300  * This is better for other programs to manipulate (like for keeping a
301  * database of IDs in documents) than humans to read.
302  */
303
304 void
305 PrintIDList()
306 {
307     ID_t        *id;
308     Element_t   *ep;
309
310     for (id=IDList; id; id=id->next) {
311         ep = id->elem;
312         fprintf(outfp, "%s:%s:%s:%d\n", id->id, ep->gi,
313                 ep->infile?ep->infile:"-", ep->lineno);
314     }
315 }
316
317 /* ______________________________________________________________________ */
318