Blame tools/smixlate.c

Packit 022b05
/*
Packit 022b05
 * smixlate.c --
Packit 022b05
 *
Packit 022b05
 *      Translate OIDs located in the input stream.
Packit 022b05
 *
Packit 022b05
 * Copyright (c) 2006 Juergen Schoenwaelder, International University Bremen.
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
#include <ctype.h>
Packit 022b05
#include <assert.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
#include "dstring.h"
Packit 022b05
Packit 022b05
static int flags;
Packit 022b05
static int aFlag = 0;	/* translate all OIDs */
Packit 022b05
static int fFlag = 0;	/* preserve formatting */
Packit 022b05
Packit 022b05
static void translate(dstring_t *token, dstring_t *subst)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    SmiSubid oid[256];
Packit 022b05
    unsigned int oidlen = 0;
Packit 022b05
    unsigned int i;
Packit 022b05
    char *p;
Packit 022b05
Packit 022b05
    assert(token && subst);
Packit 022b05
Packit 022b05
    dstring_truncate(subst, 0);
Packit 022b05
    dstring_assign(subst, dstring_str(token));
Packit 022b05
Packit 022b05
    for (oidlen = 0, p = strtok(dstring_str(token), ". "); p;
Packit 022b05
	 oidlen++, p = strtok(NULL, ". ")) {
Packit 022b05
	oid[oidlen] = strtoul(p, NULL, 0);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    smiNode = smiGetNodeByOID(oidlen, oid);
Packit 022b05
    if (smiNode &&
Packit 022b05
	(aFlag
Packit 022b05
	 || smiNode->nodekind == SMI_NODEKIND_SCALAR
Packit 022b05
	 || smiNode->nodekind == SMI_NODEKIND_COLUMN
Packit 022b05
	 || smiNode->nodekind == SMI_NODEKIND_NOTIFICATION
Packit 022b05
	 || smiNode->nodekind == SMI_NODEKIND_TABLE
Packit 022b05
	 || smiNode->nodekind == SMI_NODEKIND_ROW)) {
Packit 022b05
	dstring_assign(subst, smiNode->name);
Packit 022b05
	for (i = smiNode->oidlen; i < oidlen; i++) {
Packit 022b05
	    dstring_append_printf(subst, ".%d", oid[i]);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static void process(FILE *stream)
Packit 022b05
{
Packit 022b05
    int c, space = 0;
Packit 022b05
    enum { TXT, NUM, NUMDOT, NUMDOTNUM, OID, OIDDOT, EATSPACE } state = TXT;
Packit 022b05
    dstring_t *token, *subst;
Packit 022b05
Packit 022b05
    token = dstring_new();
Packit 022b05
    subst = dstring_new();
Packit 022b05
    
Packit 022b05
    if (! token || ! subst) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * Shall we require iswhite() or ispunct() before and after the
Packit 022b05
     * OID?
Packit 022b05
     *
Packit 022b05
     * TODO: - translate instance identifier to something meaningful
Packit 022b05
     *         (e.g. foobar["name",32]) where possible
Packit 022b05
     *       - generate warnings if instance identifier are incomplete
Packit 022b05
     *       - provide a reverse translation service (-x) (but this is
Packit 022b05
     *         more complex since it is unclear how to identify names
Packit 022b05
     *	     - make the white space magic optional
Packit 022b05
     */
Packit 022b05
Packit 022b05
    while ((c = fgetc(stream)) != EOF) {
Packit 022b05
	switch (state) {
Packit 022b05
	case TXT:
Packit 022b05
	    fputs(dstring_str(token), stdout);
Packit 022b05
	    dstring_truncate(token, 0);
Packit 022b05
	    if (isdigit(c) && c >= '0' && c <= '2') {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
		state = NUM;
Packit 022b05
	    } else {
Packit 022b05
		fputc(c, stdout);
Packit 022b05
		fflush(stdout);
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case NUM:
Packit 022b05
	    if (isdigit(c)) {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
	    } else if (c == '.') {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
		state = NUMDOT;
Packit 022b05
	    } else {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
		state = TXT;
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case NUMDOT:
Packit 022b05
	    if (isdigit(c)) {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
		state = NUMDOTNUM;
Packit 022b05
	    } else {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
		state = TXT;
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case NUMDOTNUM:
Packit 022b05
	    if (isdigit(c)) {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
	    } if (c == '.') {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
		state = OID;
Packit 022b05
	    } else {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
		state = TXT;
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case OID:
Packit 022b05
	    if (isdigit(c)) {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
	    } else if (c == '.') {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
		state = OIDDOT;
Packit 022b05
	    } else {
Packit 022b05
		translate(token, subst);
Packit 022b05
		if (fFlag) {
Packit 022b05
		    if (dstring_len(subst) < dstring_len(token)) {
Packit 022b05
			dstring_expand(subst, dstring_len(token), ' ');
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		fputs(dstring_str(subst), stdout);
Packit 022b05
		if (dstring_len(subst) > dstring_len(token)) {
Packit 022b05
		    space = dstring_len(subst) - dstring_len(token) - 1;
Packit 022b05
		} else {
Packit 022b05
		    space = 0;
Packit 022b05
		}
Packit 022b05
		if (fFlag && space > 0 && c == ' ') {
Packit 022b05
		    state = EATSPACE;
Packit 022b05
		    space--;
Packit 022b05
		} else {
Packit 022b05
		    state = TXT;
Packit 022b05
		    space = 0;
Packit 022b05
		    fputc(c, stdout);
Packit 022b05
		}
Packit 022b05
		dstring_truncate(token, 0);
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case OIDDOT:
Packit 022b05
	    if (isdigit(c)) {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
		state = OID;
Packit 022b05
	    } else {
Packit 022b05
		translate(token, subst);
Packit 022b05
		fputs(dstring_str(subst), stdout);
Packit 022b05
		fputc(c, stdout);
Packit 022b05
		dstring_truncate(token, 0);
Packit 022b05
		state = TXT;
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case EATSPACE:
Packit 022b05
	    if (c == ' ' && space > 0) {
Packit 022b05
		space--;
Packit 022b05
	    } else {
Packit 022b05
		state = TXT;
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (dstring_len(token)) {
Packit 022b05
	switch (state) {
Packit 022b05
	case TXT:
Packit 022b05
	case NUM:
Packit 022b05
	case NUMDOT:
Packit 022b05
	case NUMDOTNUM:
Packit 022b05
	    fputs(dstring_str(token), stdout);
Packit 022b05
	    dstring_truncate(token, 0);
Packit 022b05
	    fputc(c, stdout);
Packit 022b05
	    fflush(stdout);
Packit 022b05
	    break;
Packit 022b05
	case OID:
Packit 022b05
	    if (isdigit(c)) {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
	    } else {
Packit 022b05
		translate(token, subst);
Packit 022b05
		if (fFlag) {
Packit 022b05
		    if (dstring_len(subst) < dstring_len(token)) {
Packit 022b05
			dstring_expand(subst, dstring_len(token), ' ');
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		fputs(dstring_str(subst), stdout);
Packit 022b05
		if (dstring_len(subst) > dstring_len(token)) {
Packit 022b05
		    space = dstring_len(subst) - dstring_len(token) - 1;
Packit 022b05
		} else {
Packit 022b05
		    space = 0;
Packit 022b05
		}
Packit 022b05
		if (fFlag && space > 0 && c == ' ') {
Packit 022b05
		    space--;
Packit 022b05
		} else {
Packit 022b05
		    space = 0;
Packit 022b05
		    fputc(c, stdout);
Packit 022b05
		}
Packit 022b05
		dstring_truncate(token, 0);
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case OIDDOT:
Packit 022b05
	    if (isdigit(c)) {
Packit 022b05
		dstring_append_char(token, (char) c);
Packit 022b05
	    } else {
Packit 022b05
		translate(token, subst);
Packit 022b05
		fputs(dstring_str(subst), stdout);
Packit 022b05
		fputc(c, stdout);
Packit 022b05
		dstring_truncate(token, 0);
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case EATSPACE:
Packit 022b05
	    if (c == ' ' && space > 0) {
Packit 022b05
		space--;
Packit 022b05
	    } else {
Packit 022b05
		fputc(c, stdout);
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void usage()
Packit 022b05
{
Packit 022b05
    fprintf(stderr,
Packit 022b05
	    "Usage: smixlate [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
	    "  -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
	    "  -a, --all             replace all OIDs (including OID prefixes)\n"
Packit 022b05
	    "  -f, --format          preserve formatting as much as possible\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void help() { usage(); exit(0); }
Packit 022b05
static void version() { printf("smixlate " SMI_VERSION_STRING "\n"); exit(0); }
Packit 022b05
static void config(char *filename) { smiReadConfig(filename, "smixlate"); }
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
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
	{ 'a', "all",		 OPT_FLAG,   &aFlag,        0 },
Packit 022b05
	{ 'f', "format",         OPT_FLAG,   &fFlag,	    0 },
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
	{ '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("smixlate");
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
    for (i = 1; i < argc; i++) {
Packit 022b05
	if (smiLoadModule(argv[i]) == NULL) {
Packit 022b05
	    fprintf(stderr, "smixlate: cannot locate module `%s'\n",
Packit 022b05
		    argv[i]);
Packit 022b05
	    smiExit();
Packit 022b05
	    exit(1);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
Packit 022b05
    process(stdin);
Packit 022b05
Packit 022b05
    smiExit();
Packit 022b05
Packit 022b05
    return 0;
Packit 022b05
}