Imported Upstream version 0.4.8
[platform/upstream/libsmi.git] / tools / dump-compliance.c
1 /*
2  * dump-compliances.c --
3  *
4  *      Operations to dump compliances in a human readable format.
5  *
6  * Copyright (c) 2005 J. Schoenwaelder, International University Bremen.
7  *
8  * See the file "COPYING" for information on usage and redistribution
9  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10  *
11  * @(#) $Id: dump-compliances.c 1571 2003-07-14 22:58:42Z schoenw $
12  */
13
14 #include <config.h>
15
16 #include <stdio.h>
17 #include <string.h>
18
19 #include "smi.h"
20 #include "smidump.h"
21
22
23 static char *getFlags(SmiNode *smiNode)
24 {
25
26     switch (smiNode->access) {
27     case SMI_ACCESS_UNKNOWN:
28         return "---";
29     case SMI_ACCESS_NOT_ACCESSIBLE:
30         return "---";
31     case SMI_ACCESS_NOTIFY:
32         return "--n";
33     case SMI_ACCESS_EVENT_ONLY:
34         return "--n";
35     case SMI_ACCESS_READ_ONLY:
36         return "r-n";
37     case SMI_ACCESS_READ_WRITE:
38         return "rwn";
39     case SMI_ACCESS_NOT_IMPLEMENTED:
40         return "---";
41     case SMI_ACCESS_INSTALL:
42         return "-i-";
43     case SMI_ACCESS_INSTALL_NOTIFY:
44         return "-in";
45     case SMI_ACCESS_REPORT_ONLY:
46         return "--r";
47     }
48
49     return "";
50 }
51
52
53
54 static char getStatusChar(SmiStatus status)
55 {
56     switch (status) {
57     case SMI_STATUS_UNKNOWN:
58         return '+';
59     case SMI_STATUS_CURRENT:
60         return '+';
61     case SMI_STATUS_DEPRECATED:
62         return 'x';
63     case SMI_STATUS_MANDATORY:
64         return '+';
65     case SMI_STATUS_OPTIONAL:
66         return '+';
67     case SMI_STATUS_OBSOLETE:
68         return 'o';
69     }
70
71     return ' ';
72 }
73
74
75
76 static char *getTypeName(SmiNode *smiNode)
77 {
78     char *type;
79     SmiType *smiType, *parentType;
80
81     smiType = smiGetNodeType(smiNode);
82
83     if (!smiType || smiNode->nodekind == SMI_NODEKIND_TABLE)
84         return NULL;
85     
86     if (smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
87         parentType = smiGetParentType(smiType);
88         if (!parentType)
89             return NULL;
90         smiType = parentType;
91     }
92
93     type = xstrdup(smiType->name);
94     return type;
95 }
96
97
98
99 static void fprintGroup(FILE *f, SmiNode *smiNode, char c,
100                         int *typelen, int *namelen, int pass)
101 {
102     SmiElement *smiElement;
103     SmiNode *smiObject;
104     SmiModule *smiModule;
105     char *type_name;
106     int tlen = 9, nlen = 9;
107
108     switch (smiNode->nodekind) {
109     case SMI_NODEKIND_GROUP:
110         for (smiElement = smiGetFirstElement(smiNode);
111              smiElement;
112              smiElement = smiGetNextElement(smiElement)) {
113             smiObject = smiGetElementNode(smiElement);
114             smiModule = smiGetNodeModule(smiNode);
115             type_name = getTypeName(smiObject);
116             if (pass == 1) {
117                 if (type_name) {
118                     int newlen = strlen(type_name);
119                     tlen = (tlen < newlen) ? newlen : tlen;
120                 }
121                 if (smiObject->name) {
122                     int newlen = strlen(smiObject->name);
123                     nlen = (nlen < newlen) ? newlen : nlen;
124                 }
125             } else if (pass == 2) {
126                 fprintf(f, "  %c%c%s %-*s %-*s (%s)\n",
127                         getStatusChar(smiObject->status), c,
128                         getFlags(smiObject),
129                         *typelen, type_name ? type_name : "-",
130                         *namelen, smiObject->name, smiNode->name);
131             }
132             xfree(type_name);
133         }
134         break;
135     case SMI_NODEKIND_SCALAR:
136     case SMI_NODEKIND_COLUMN:
137         smiObject = smiNode;
138         type_name = getTypeName(smiObject);
139         if (pass == 1) {
140             if (type_name) {
141                 int newlen = strlen(type_name);
142                 tlen = tlen < newlen ? newlen : tlen;
143             }
144             if (smiObject->name) {
145                 int newlen = strlen(smiObject->name);
146                 nlen = (nlen < newlen) ? newlen : nlen;
147             }
148         } else if (pass == 2) {
149             fprintf(f, "  %c%c%s %-*s %s\n",
150                     getStatusChar(smiObject->status), 'r',
151                     getFlags(smiObject),
152                     *typelen, type_name ? type_name : "-",
153                     smiObject->name);
154         }
155         xfree(type_name);
156         break;
157     default:
158         break;
159     }
160
161     if (pass == 1) {
162         if (typelen) *typelen = tlen;
163         if (namelen) *namelen = nlen;
164     }
165 }
166
167
168
169 static void fprintCompliance(FILE *f, SmiNode *smiNode,
170                              int *typelen, int *namelen, int pass)
171 {
172     SmiElement *smiElement;
173     SmiOption *smiOption;
174     SmiRefinement *smiRefinement;
175     int tlen = 0, nlen = 0;
176
177     for (smiElement = smiGetFirstElement(smiNode);
178          smiElement;
179          smiElement = smiGetNextElement(smiElement)) {
180         fprintGroup(f, smiGetElementNode(smiElement), 'm',
181                     (pass == 1) ? &tlen : typelen,
182                     (pass == 1) ? &nlen : namelen, pass);
183         if (pass == 1) {
184             if (typelen) {
185                 *typelen = *typelen < tlen ? tlen : *typelen;
186             }
187             if (namelen) {
188                 *namelen = *namelen < nlen ? nlen : *namelen;
189             }
190         }
191     }
192
193     for(smiOption = smiGetFirstOption(smiNode);
194         smiOption;
195         smiOption = smiGetNextOption(smiOption)) {
196         fprintGroup(f, smiGetOptionNode(smiOption), 'c',
197                     (pass == 1) ? &tlen : typelen,
198                     (pass == 1) ? &nlen : namelen, pass);
199         if (pass == 1) {
200             if (typelen) {
201                 *typelen = *typelen < tlen ? tlen : *typelen;
202             }
203             if (namelen) {
204                 *namelen = *namelen < nlen ? nlen : *namelen;
205             }
206         }
207     }
208
209     for (smiRefinement = smiGetFirstRefinement(smiNode);
210          smiRefinement;
211          smiRefinement = smiGetNextRefinement(smiRefinement)) {
212         fprintGroup(f, smiGetRefinementNode(smiRefinement), 'r',
213                     (pass == 1) ? &tlen : typelen,
214                     (pass == 1) ? &nlen : namelen, pass);
215         if (pass == 1) {
216             if (typelen) {
217                 *typelen = *typelen < tlen ? tlen : *typelen;
218             }
219             if (namelen) {
220                 *namelen = *namelen < nlen ? nlen : *namelen;
221             }
222         }
223     }
224 }
225
226
227
228 static void fprintCompliances(FILE *f, SmiModule *smiModule)
229 {
230     SmiNode *smiNode;
231     int i, typelen = 0, namelen = 0;
232
233     for (i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_COMPLIANCE);
234          smiNode;
235          smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COMPLIANCE), i++) {
236         fprintf(f, "%s%s:\n", i ? "\n" : "", smiNode->name);
237         fprintCompliance(f, smiNode, &typelen, &namelen, 1);
238         fprintCompliance(f, smiNode, &typelen, &namelen, 2);
239     }
240 }
241
242
243
244 static void
245 dumpCompliances(int modc, SmiModule **modv, int flags, char *output)
246 {
247     int     i;
248     FILE    *f = stdout;
249     
250     if (output) {
251         f = fopen(output, "w");
252         if (!f) {
253             fprintf(stderr, "smidump: cannot open %s for writing: ", output);
254             perror(NULL);
255             exit(1);
256         }
257     }
258
259     for (i = 0; i < modc; i++) {
260         if (! (flags & SMIDUMP_FLAG_SILENT)) {
261             fprintf(f, "# %s compliances (generated by smidump "
262                     SMI_VERSION_STRING ")\n\n", modv[i]->name);
263         }
264
265         if (! (flags & SMIDUMP_FLAG_SILENT) && (flags & SMIDUMP_FLAG_ERROR)) {
266             fprintf(f, "# WARNING: this output may be incorrect due to "
267                     "significant parse errors\n\n");
268         }
269         
270         fprintCompliances(f, modv[i]);
271     }
272
273     if (fflush(f) || ferror(f)) {
274         perror("smidump: write error");
275         exit(1);
276     }
277
278     if (output) {
279         fclose(f);
280     }
281 }
282
283
284
285 void initCompliances()
286 {
287     static SmidumpDriver driver = {
288         "compliances",
289         dumpCompliances,
290         SMI_FLAG_NODESCR,
291         SMIDUMP_DRIVER_CANT_UNITE,
292         "compliances with all included objects / notifications",
293         /* opt, */ NULL,
294         NULL
295     };
296     
297     smidumpRegisterDriver(&driver);
298 }