|
Packit |
022b05 |
/*
|
|
Packit |
022b05 |
* dump-imports.c --
|
|
Packit |
022b05 |
*
|
|
Packit |
022b05 |
* Operations to dump import hierarchies in a human readable format.
|
|
Packit |
022b05 |
*
|
|
Packit |
022b05 |
* Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
|
|
Packit |
022b05 |
* Copyright (c) 1999 J. Schoenwaelder, Technical University of Braunschweig.
|
|
Packit |
022b05 |
*
|
|
Packit |
022b05 |
* See the file "COPYING" for information on usage and redistribution
|
|
Packit |
022b05 |
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
Packit |
022b05 |
*
|
|
Packit |
022b05 |
* @(#) $Id: dump-imports.c 5758 2006-08-16 21:10:05Z schoenw $
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
#include <config.h>
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
#include <stdio.h>
|
|
Packit |
022b05 |
#include <string.h>
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
#include "smi.h"
|
|
Packit |
022b05 |
#include "smidump.h"
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
typedef struct Imports {
|
|
Packit |
022b05 |
char *module;
|
|
Packit |
022b05 |
int count;
|
|
Packit |
022b05 |
struct Imports *nextPtr;
|
|
Packit |
022b05 |
} Imports;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static Imports *getImports(SmiModule *smiModule, int *n)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
SmiImport *smiImport;
|
|
Packit |
022b05 |
Imports *imports;
|
|
Packit |
022b05 |
int i;
|
|
Packit |
022b05 |
size_t size;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (smiImport = smiGetFirstImport(smiModule), *n = 0;
|
|
Packit |
022b05 |
smiImport; smiImport = smiGetNextImport(smiImport)) {
|
|
Packit |
022b05 |
(*n)++;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
size = (*n + 1) * sizeof(Imports);
|
|
Packit |
022b05 |
imports = xmalloc(size);
|
|
Packit |
022b05 |
memset(imports, 0, size);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (smiImport = smiGetFirstImport(smiModule), *n = 0;
|
|
Packit |
022b05 |
smiImport; smiImport = smiGetNextImport(smiImport)) {
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (!smiImport->module) continue;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 0; i < *n; i++) {
|
|
Packit |
022b05 |
if (strcmp(smiImport->module, imports[i].module) == 0) {
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (i == *n) {
|
|
Packit |
022b05 |
imports[i].module = xstrdup(smiImport->module);
|
|
Packit |
022b05 |
if (imports[i].module) {
|
|
Packit |
022b05 |
imports[i].count = 0;
|
|
Packit |
022b05 |
(*n)++;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
imports[i].count++;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
return imports;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void freeImports(Imports *imports, int n)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int i;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 0; i < n; i++) {
|
|
Packit |
022b05 |
xfree(imports[i].module);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
xfree(imports);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static int fprintImports(FILE *f, SmiModule *smiModule, char *prefix,
|
|
Packit |
022b05 |
Imports *backtrace)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
SmiModule *smiModule2;
|
|
Packit |
022b05 |
Imports *imports, *imp;
|
|
Packit |
022b05 |
int i, n, recurse = 0, done = 0;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (imp = backtrace; imp; imp = imp->nextPtr) {
|
|
Packit |
022b05 |
if (strcmp(imp->module, smiModule->name) == 0) {
|
|
Packit |
022b05 |
fprintf(stderr, "%s (recursion - aborted)\n", prefix);
|
|
Packit |
022b05 |
return 0;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
imp = (Imports *) xmalloc(sizeof(Imports));
|
|
Packit |
022b05 |
imp->module = smiModule->name;
|
|
Packit |
022b05 |
imp->nextPtr = backtrace;
|
|
Packit |
022b05 |
backtrace = imp;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
imports = getImports(smiModule, &n);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 0; i < n; i++) {
|
|
Packit |
022b05 |
char *newprefix;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
smiModule2 = smiGetModule(imports[i].module);
|
|
Packit |
022b05 |
recurse = (NULL == smiGetFirstImport(smiModule2));
|
|
Packit |
022b05 |
if (recurse) {
|
|
Packit |
022b05 |
fprintf(f, "%s |\n", prefix);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
fprintf(f, "%s +--%s [%d identifier%s]\n", prefix, imports[i].module,
|
|
Packit |
022b05 |
imports[i].count, imports[i].count > 1 ? "s" : "");
|
|
Packit |
022b05 |
newprefix = xmalloc(strlen(prefix)+10);
|
|
Packit |
022b05 |
strcpy(newprefix, prefix);
|
|
Packit |
022b05 |
if (i == n-1) {
|
|
Packit |
022b05 |
strcat(newprefix, " ");
|
|
Packit |
022b05 |
} else {
|
|
Packit |
022b05 |
strcat(newprefix, " |");
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
done = fprintImports(f, smiModule2, newprefix, backtrace);
|
|
Packit |
022b05 |
if (! recurse && done) {
|
|
Packit |
022b05 |
if (i == n-1) {
|
|
Packit |
022b05 |
fprintf(f, "%s \n", prefix);
|
|
Packit |
022b05 |
} else {
|
|
Packit |
022b05 |
fprintf(f, "%s |\n", prefix);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
xfree(newprefix);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
freeImports(imports, n);
|
|
Packit |
022b05 |
xfree(backtrace);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
return recurse;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void dumpImports(int modc, SmiModule **modv, int flags, char *output)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int i;
|
|
Packit |
022b05 |
FILE *f = stdout;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (output) {
|
|
Packit |
022b05 |
f = fopen(output, "w");
|
|
Packit |
022b05 |
if (!f) {
|
|
Packit |
022b05 |
fprintf(stderr, "smidump: cannot open %s for writing: ", output);
|
|
Packit |
022b05 |
perror(NULL);
|
|
Packit |
022b05 |
exit(1);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 0; i < modc; i++) {
|
|
Packit |
022b05 |
if (! (flags & SMIDUMP_FLAG_SILENT)) {
|
|
Packit |
022b05 |
fprintf(f, "# %s imports tree (generated by smidump "
|
|
Packit |
022b05 |
SMI_VERSION_STRING ")\n\n", modv[i]->name);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (! (flags & SMIDUMP_FLAG_SILENT) && (flags & SMIDUMP_FLAG_ERROR)) {
|
|
Packit |
022b05 |
fprintf(f, "# WARNING: this output may be incorrect due to "
|
|
Packit |
022b05 |
"significant parse errors\n\n");
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
fprintf(f, "%s\n", modv[i]->name);
|
|
Packit |
022b05 |
fprintImports(f, modv[i], "", NULL);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (fflush(f) || ferror(f)) {
|
|
Packit |
022b05 |
perror("smidump: write error");
|
|
Packit |
022b05 |
exit(1);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (output) {
|
|
Packit |
022b05 |
fclose(f);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
void initImports()
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static SmidumpDriver driver = {
|
|
Packit |
022b05 |
"imports",
|
|
Packit |
022b05 |
dumpImports,
|
|
Packit |
022b05 |
SMI_FLAG_NODESCR,
|
|
Packit |
022b05 |
SMIDUMP_DRIVER_CANT_UNITE,
|
|
Packit |
022b05 |
"recursive list of all imports",
|
|
Packit |
022b05 |
NULL,
|
|
Packit |
022b05 |
NULL
|
|
Packit |
022b05 |
};
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
smidumpRegisterDriver(&driver);
|
|
Packit |
022b05 |
}
|