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
getImports(SmiModule * smiModule,int * n)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
freeImports(Imports * imports,int n)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
fprintImports(FILE * f,SmiModule * smiModule,char * prefix,Imports * backtrace)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
dumpImports(int modc,SmiModule ** modv,int flags,char * output)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
initImports()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 }
200