Blame tools/dump-imports.c

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
}