Imported Upstream version 0.4.8
[platform/upstream/libsmi.git] / tools / dump-imports.c
1 /*
2  * dump-imports.c --
3  *
4  *      Operations to dump import hierarchies in a human readable format.
5  *
6  * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
7  * Copyright (c) 1999 J. Schoenwaelder, Technical University of Braunschweig.
8  *
9  * See the file "COPYING" for information on usage and redistribution
10  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11  *
12  * @(#) $Id: dump-imports.c 5758 2006-08-16 21:10:05Z schoenw $
13  */
14
15 #include <config.h>
16
17 #include <stdio.h>
18 #include <string.h>
19
20 #include "smi.h"
21 #include "smidump.h"
22
23
24 typedef struct Imports {
25     char *module;
26     int  count;
27     struct Imports *nextPtr;
28 } Imports;
29
30
31
32 static Imports *getImports(SmiModule *smiModule, int *n)
33 {
34     SmiImport *smiImport;
35     Imports   *imports;
36     int       i;
37     size_t    size;
38     
39     for (smiImport = smiGetFirstImport(smiModule), *n = 0;
40          smiImport; smiImport = smiGetNextImport(smiImport)) {
41         (*n)++;
42     }
43
44     size = (*n + 1) * sizeof(Imports);
45     imports = xmalloc(size);
46     memset(imports, 0, size);
47
48     for (smiImport = smiGetFirstImport(smiModule), *n = 0;
49          smiImport; smiImport = smiGetNextImport(smiImport)) {
50         
51         if (!smiImport->module) continue;
52         
53         for (i = 0; i < *n; i++) {
54             if (strcmp(smiImport->module, imports[i].module) == 0) {
55                 break;
56             }
57         }
58         
59         if (i == *n) {
60             imports[i].module = xstrdup(smiImport->module);
61             if (imports[i].module) {
62                 imports[i].count = 0;
63                 (*n)++;
64             }
65         }
66         imports[i].count++;
67     }
68
69     return imports;
70 }
71
72
73
74 static void freeImports(Imports *imports, int n)
75 {
76     int i;
77
78     for (i = 0; i < n; i++) {
79         xfree(imports[i].module);
80     }
81
82     xfree(imports);
83 }
84
85
86
87 static int fprintImports(FILE *f, SmiModule *smiModule, char *prefix,
88                          Imports *backtrace)
89 {
90     SmiModule *smiModule2;
91     Imports *imports, *imp;
92     int     i, n, recurse = 0, done = 0;
93
94     for (imp = backtrace; imp; imp = imp->nextPtr) {
95         if (strcmp(imp->module, smiModule->name) == 0) {
96             fprintf(stderr, "%s  (recursion - aborted)\n", prefix);
97             return 0;
98         }
99     }
100
101     imp = (Imports *) xmalloc(sizeof(Imports));
102     imp->module = smiModule->name;
103     imp->nextPtr = backtrace;
104     backtrace = imp;
105
106     imports = getImports(smiModule, &n);
107
108     for (i = 0; i < n; i++) {
109         char *newprefix;
110
111         smiModule2 = smiGetModule(imports[i].module);
112         recurse = (NULL == smiGetFirstImport(smiModule2));
113         if (recurse) {
114             fprintf(f, "%s  |\n", prefix);
115         }
116         fprintf(f, "%s  +--%s [%d identifier%s]\n", prefix, imports[i].module, 
117                 imports[i].count, imports[i].count > 1 ? "s" : "");
118         newprefix = xmalloc(strlen(prefix)+10);
119         strcpy(newprefix, prefix);
120         if (i == n-1) {
121             strcat(newprefix, "   ");
122         } else {
123             strcat(newprefix, "  |");
124         }
125         done = fprintImports(f, smiModule2, newprefix, backtrace);
126         if (! recurse && done) {
127             if (i == n-1) {
128                 fprintf(f, "%s   \n", prefix);
129             } else {
130                 fprintf(f, "%s  |\n", prefix);
131             }
132         }
133         xfree(newprefix);
134     }
135
136     freeImports(imports, n);
137     xfree(backtrace);
138
139     return recurse;
140 }
141
142
143
144 static void dumpImports(int modc, SmiModule **modv, int flags, char *output)
145 {
146     int  i;
147     FILE *f = stdout;
148     
149     if (output) {
150         f = fopen(output, "w");
151         if (!f) {
152             fprintf(stderr, "smidump: cannot open %s for writing: ", output);
153             perror(NULL);
154             exit(1);
155         }
156     }
157
158     for (i = 0; i < modc; i++) {
159         if (! (flags & SMIDUMP_FLAG_SILENT)) {
160             fprintf(f, "# %s imports tree (generated by smidump "
161                     SMI_VERSION_STRING ")\n\n", modv[i]->name);
162         }
163         
164         if (! (flags & SMIDUMP_FLAG_SILENT) && (flags & SMIDUMP_FLAG_ERROR)) {
165             fprintf(f, "# WARNING: this output may be incorrect due to "
166                     "significant parse errors\n\n");
167         }
168         
169         fprintf(f, "%s\n", modv[i]->name);
170         fprintImports(f, modv[i], "", NULL);
171     }
172
173     if (fflush(f) || ferror(f)) {
174         perror("smidump: write error");
175         exit(1);
176     }
177
178     if (output) {
179         fclose(f);
180     }
181 }
182
183
184
185 void initImports()
186 {
187     
188     static SmidumpDriver driver = {
189         "imports",
190         dumpImports,
191         SMI_FLAG_NODESCR,
192         SMIDUMP_DRIVER_CANT_UNITE,
193         "recursive list of all imports",
194         NULL,
195         NULL
196     };
197     
198     smidumpRegisterDriver(&driver);
199 }