|
Packit |
022b05 |
/*
|
|
Packit |
022b05 |
* smilint.c --
|
|
Packit |
022b05 |
*
|
|
Packit |
022b05 |
* MIB module checker main program.
|
|
Packit |
022b05 |
*
|
|
Packit |
022b05 |
* Copyright (c) 1999 Frank Strauss, 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: smilint.c 1867 2004-10-06 13:45:31Z strauss $
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
#include <config.h>
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
#include <stdlib.h>
|
|
Packit |
022b05 |
#include <stdio.h>
|
|
Packit |
022b05 |
#include <string.h>
|
|
Packit |
022b05 |
#ifdef HAVE_UNISTD_H
|
|
Packit |
022b05 |
#include <unistd.h>
|
|
Packit |
022b05 |
#endif
|
|
Packit |
022b05 |
#ifdef HAVE_WIN_H
|
|
Packit |
022b05 |
#include "win.h"
|
|
Packit |
022b05 |
#endif
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
#include "smi.h"
|
|
Packit |
022b05 |
#include "shhopt.h"
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*
|
|
Packit |
022b05 |
* These are functions that are not officially exported by the libsmi.
|
|
Packit |
022b05 |
* See the original prototype definitions in lib/error.h.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
extern int smiGetErrorSeverity(int id);
|
|
Packit |
022b05 |
extern char* smiGetErrorTag(int id);
|
|
Packit |
022b05 |
extern char* smiGetErrorMsg(int id);
|
|
Packit |
022b05 |
extern char* smiGetErrorDescription(int id);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static int mFlag = 0; /* show the name for error messages */
|
|
Packit |
022b05 |
static int sFlag = 0; /* show the severity for error messages */
|
|
Packit |
022b05 |
static int eFlag = 0; /* print the list of possible error messages */
|
|
Packit |
022b05 |
static int flags;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
typedef struct Error {
|
|
Packit |
022b05 |
int id;
|
|
Packit |
022b05 |
int severity;
|
|
Packit |
022b05 |
char *tag;
|
|
Packit |
022b05 |
char *msg;
|
|
Packit |
022b05 |
char *description;
|
|
Packit |
022b05 |
int used;
|
|
Packit |
022b05 |
} Error;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static Error *errors = NULL;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void fold(FILE *f, int indent, const char *msg)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
const char *p, *s;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (! msg) {
|
|
Packit |
022b05 |
fprintf(f, "\n");
|
|
Packit |
022b05 |
return;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (s = msg; *s; s++) {
|
|
Packit |
022b05 |
for (p = s; *p && *p != '\n'; p++) ;
|
|
Packit |
022b05 |
if (*p) {
|
|
Packit |
022b05 |
fprintf(f, "%.*s\n%*s", p - s, s, indent, "");
|
|
Packit |
022b05 |
s = p;
|
|
Packit |
022b05 |
} else {
|
|
Packit |
022b05 |
fprintf(f, "%.*s\n", p - s, s);
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static int compare(const void *v1, const void *v2)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
Error *err1 = (Error *) v1;
|
|
Packit |
022b05 |
Error *err2 = (Error *) v2;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (err1->severity < err2->severity) {
|
|
Packit |
022b05 |
return -1;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
if (err1->severity > err2->severity) {
|
|
Packit |
022b05 |
return 1;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
return strcmp(err1->msg, err2->msg);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static Error* errors_new()
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int i, cnt;
|
|
Packit |
022b05 |
Error *errors;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (cnt = 0; smiGetErrorSeverity(cnt) >= 0; cnt++) ;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
errors = malloc((cnt + 1) * sizeof(Error));
|
|
Packit |
022b05 |
if (! errors) {
|
|
Packit |
022b05 |
fprintf(stderr, "smilint: malloc failed - running out of memory\n");
|
|
Packit |
022b05 |
exit(1);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
memset(errors, 0, (cnt + 1) * sizeof(Error));
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 0; i < cnt; i++) {
|
|
Packit |
022b05 |
errors[i].id = i;
|
|
Packit |
022b05 |
errors[i].severity = smiGetErrorSeverity(i);
|
|
Packit |
022b05 |
errors[i].tag = smiGetErrorTag(i);
|
|
Packit |
022b05 |
errors[i].msg = smiGetErrorMsg(i);
|
|
Packit |
022b05 |
errors[i].description = smiGetErrorDescription(i);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
qsort(errors, cnt, sizeof(Error), compare);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
return errors;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void display_one(FILE *f, Error *error)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
const int indent = 12;
|
|
Packit |
022b05 |
char *type, *tag;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
type = (error->severity <= 3) ? "Error:" : "Warning:";
|
|
Packit |
022b05 |
tag = (error->tag && strlen(error->tag))
|
|
Packit |
022b05 |
? error->tag : "<xxx-missing-xxx>";
|
|
Packit |
022b05 |
fprintf(f, "%-*s %s (level %d%s)\n",
|
|
Packit |
022b05 |
indent, type, tag, error->severity & 127,
|
|
Packit |
022b05 |
error->severity & 128 ? ", ignored" : "");
|
|
Packit |
022b05 |
fprintf(f, "%-*s %s\n", indent, "Message:",
|
|
Packit |
022b05 |
error->msg ? error->msg : "");
|
|
Packit |
022b05 |
if (error->description) {
|
|
Packit |
022b05 |
fprintf(f, "%-*s ", indent, "Description:");
|
|
Packit |
022b05 |
fold(f, indent + 1, error->description);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void display_all(Error *errors)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int i;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 0; errors[i].msg; i++) {
|
|
Packit |
022b05 |
if (i) printf("\n");
|
|
Packit |
022b05 |
display_one(stdout, errors + i);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void display_used(Error *errors)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int i, n;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 0, n = 0; errors[i].msg; i++) {
|
|
Packit |
022b05 |
if (errors[i].used && errors[i].description) n++;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (! n) {
|
|
Packit |
022b05 |
return;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
fprintf(stderr,
|
|
Packit |
022b05 |
"\nAdditional descriptions of some error/warning messages:\n");
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 0; errors[i].msg; i++) {
|
|
Packit |
022b05 |
if (! errors[i].used || !errors[i].description) continue;
|
|
Packit |
022b05 |
if (i) fprintf(stderr, "\n");
|
|
Packit |
022b05 |
display_one(stderr, errors + i);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void usage()
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
fprintf(stderr,
|
|
Packit |
022b05 |
"Usage: smilint [options] [module or path ...]\n"
|
|
Packit |
022b05 |
" -V, --version show version and license information\n"
|
|
Packit |
022b05 |
" -h, --help show usage information\n"
|
|
Packit |
022b05 |
" -c, --config=file load a specific configuration file\n"
|
|
Packit |
022b05 |
" -p, --preload=module preload <module>\n"
|
|
Packit |
022b05 |
" -e, --error-list print list of known error messages\n"
|
|
Packit |
022b05 |
" -m, --error-names print the name of errors in braces\n"
|
|
Packit |
022b05 |
" -s, --severity print the severity of errors in brackets\n"
|
|
Packit |
022b05 |
" -r, --recursive print errors also for imported modules\n"
|
|
Packit |
022b05 |
" -l, --level=level set maximum level of errors and warnings\n"
|
|
Packit |
022b05 |
" -i, --ignore=prefix ignore errors matching prefix pattern\n"
|
|
Packit |
022b05 |
" -I, --noignore=prefix do not ignore errors matching prefix pattern\n");
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void help() { usage(); exit(0); }
|
|
Packit |
022b05 |
static void version() { printf("smilint " SMI_VERSION_STRING "\n"); exit(0); }
|
|
Packit |
022b05 |
static void config(char *filename) { smiReadConfig(filename, "smilint"); }
|
|
Packit |
022b05 |
static void preload(char *module) { smiLoadModule(module); }
|
|
Packit |
022b05 |
static void recursive() { flags |= SMI_FLAG_RECURSIVE; smiSetFlags(flags); }
|
|
Packit |
022b05 |
static void level(int lev) { smiSetErrorLevel(lev); }
|
|
Packit |
022b05 |
static void ignore(char *ign) { smiSetSeverity(ign, 128); }
|
|
Packit |
022b05 |
static void noignore(char *ign) { smiSetSeverity(ign, -1); }
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void
|
|
Packit |
022b05 |
errorHandler(char *path, int line, int severity, char *msg, char *tag)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int i;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (path) {
|
|
Packit |
022b05 |
fprintf(stderr, "%s:%d: ", path, line);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
if (sFlag) {
|
|
Packit |
022b05 |
fprintf(stderr, "[%d] ", severity);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
if (mFlag) {
|
|
Packit |
022b05 |
fprintf(stderr, "{%s} ", tag);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
switch (severity) {
|
|
Packit |
022b05 |
case 4:
|
|
Packit |
022b05 |
case 5:
|
|
Packit |
022b05 |
fprintf(stderr, "warning: ");
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
case 6:
|
|
Packit |
022b05 |
fprintf(stderr, "info: ");
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
fprintf(stderr, "%s\n", msg);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (severity <= 0) {
|
|
Packit |
022b05 |
exit(1);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/* If we are supposed to generate error descriptions, locate this
|
|
Packit |
022b05 |
* error in our error list and increment its usage counter. Note
|
|
Packit |
022b05 |
* that we assume that error tags are unique (and we should better
|
|
Packit |
022b05 |
* check for this somewhere). */
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (errors) {
|
|
Packit |
022b05 |
for (i = 0; errors[i].msg; i++) {
|
|
Packit |
022b05 |
if (strcmp(errors[i].tag, tag) == 0) {
|
|
Packit |
022b05 |
errors[i].used++;
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
int main(int argc, char *argv[])
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int i;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static optStruct opt[] = {
|
|
Packit |
022b05 |
/* short long type var/func special */
|
|
Packit |
022b05 |
{ 'h', "help", OPT_FLAG, help, OPT_CALLFUNC },
|
|
Packit |
022b05 |
{ 'V', "version", OPT_FLAG, version, OPT_CALLFUNC },
|
|
Packit |
022b05 |
{ 'c', "config", OPT_STRING, config, OPT_CALLFUNC },
|
|
Packit |
022b05 |
{ 'p', "preload", OPT_STRING, preload, OPT_CALLFUNC },
|
|
Packit |
022b05 |
{ 'e', "error-list", OPT_FLAG, &eFlag, 0 },
|
|
Packit |
022b05 |
{ 'm', "error-names", OPT_FLAG, &mFlag, 0 },
|
|
Packit |
022b05 |
{ 's', "severity", OPT_FLAG, &sFlag, 0 },
|
|
Packit |
022b05 |
{ 'r', "recursive", OPT_FLAG, recursive, OPT_CALLFUNC },
|
|
Packit |
022b05 |
{ 'l', "level", OPT_INT, level, OPT_CALLFUNC },
|
|
Packit |
022b05 |
{ 'i', "ignore", OPT_STRING, ignore, OPT_CALLFUNC },
|
|
Packit |
022b05 |
{ 'I', "noignore", OPT_STRING, noignore, OPT_CALLFUNC },
|
|
Packit |
022b05 |
{ 0, 0, OPT_END, 0, 0 } /* no more options */
|
|
Packit |
022b05 |
};
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 1; i < argc; i++)
|
|
Packit |
022b05 |
if ((strstr(argv[i], "-c") == argv[i]) ||
|
|
Packit |
022b05 |
(strstr(argv[i], "--config") == argv[i])) break;
|
|
Packit |
022b05 |
if (i == argc)
|
|
Packit |
022b05 |
smiInit("smilint");
|
|
Packit |
022b05 |
else
|
|
Packit |
022b05 |
smiInit(NULL);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
flags = smiGetFlags();
|
|
Packit |
022b05 |
flags |= SMI_FLAG_ERRORS;
|
|
Packit |
022b05 |
flags |= SMI_FLAG_NODESCR;
|
|
Packit |
022b05 |
smiSetFlags(flags);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
optParseOptions(&argc, argv, opt, 0);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (eFlag) {
|
|
Packit |
022b05 |
mFlag = 1;
|
|
Packit |
022b05 |
errors = errors_new();
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (sFlag || mFlag) {
|
|
Packit |
022b05 |
smiSetErrorHandler(errorHandler);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (eFlag && argc == 1) {
|
|
Packit |
022b05 |
if (errors) {
|
|
Packit |
022b05 |
display_all(errors);
|
|
Packit |
022b05 |
free(errors);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
smiExit();
|
|
Packit |
022b05 |
return 0;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
for (i = 1; i < argc; i++) {
|
|
Packit |
022b05 |
if (smiLoadModule(argv[i]) == NULL) {
|
|
Packit |
022b05 |
fprintf(stderr, "smilint: cannot locate module `%s'\n",
|
|
Packit |
022b05 |
argv[i]);
|
|
Packit |
022b05 |
smiExit();
|
|
Packit |
022b05 |
exit(1);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (eFlag) {
|
|
Packit |
022b05 |
if (errors) {
|
|
Packit |
022b05 |
display_used(errors);
|
|
Packit |
022b05 |
free(errors);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
smiExit();
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
return 0;
|
|
Packit |
022b05 |
}
|