/*
 * $RCSfile: ptbldump.c,v $
 *
 * x-kernel v3.3
 *
 * Copyright (c) 1993,1991,1990,1996  Arizona Board of Regents
 *
 * $Log: ptbldump.c,v $
 * Revision 1.3  1996/06/08 00:19:35  slm
 * Added stub for msgToughDestroy().
 *
 * Revision 1.2  1996/01/27  00:20:33  slm
 * Updated copyright, version and msgWalkToughNext.
 *
 * Revision 1.1  1995/07/29  03:12:54  slm
 * Initial revision
 *
 * Revision 1.13.1.2.1.1  1994/11/14  15:51:03  hkaram
 * New branch
 *
 * Revision 1.13.1.2  1994/08/17  17:31:51  hkaram
 * Changed the function declaration of addMapPair to
 * satisfy irix's strict arg checks
 *
 * Revision 1.13.1.1  1994/06/08  21:56:15  menze
 * Added bogus definitions of scout_malloc, scout_free and scout_abort so
 * we can build on the alphas.  <ouch>
 *
 * Revision 1.13  1994/04/13  23:58:37  davidm
 * (doEntry): e->id is a "long" but it was printed as "%d"---fixed to "%ld".
 *
 * Revision 1.12  1994/04/13  23:42:23  davidm
 * (doEntry): Parameter "value" now declared as VOID* as it should be.
 *
 * Revision 1.11  1994/02/05  00:10:31  menze
 *   [ 1994/02/03          menze ]
 *   Tweaked the bogus-definition section a bit for Irix.
 *   Added a cast.
 */

/* 
 * Builds a protocol table with files listed on the command line and
 * then dumps C code which can rebuild the table.
 */

#include <ctype.h>
#include <stdio.h>
#include "xtype.h"
#include "idmap.h"
#include "prottbl.h"
#include "prottbl_i.h"
#include "romopt.h"

/* 
 * These are some bogus definitions to allow us to only link some
 * of the x-kernel files
 */
void Kabort(s) char *s; {}
struct protl *protl_tab[1];
#ifndef xFree
void     xFree(a) char *a; {}
#endif
void     xTraceLock() {}
void     xTraceUnlock() {}
void     xAssertPrint(s, n) char *s; int n; {}
XkReturn findRomOpts(str, opt, numOpts, arg)
char     *str;
RomOpt   *opt;
int      numOpts;
VOID     *arg;
{    
}

#ifdef SCOUT

void *
scout_malloc(int n)
{
    return (void *)malloc(n);
}

void scout_free(void *p) {}
void scout_abort(const char *f, ...) {}

#else

char *
xMalloc(n)
unsigned n;
{
    return (char *)malloc(n);
}

#endif

char *protocolTables[1] = { 0 };

#define DECL 0
#define MAPS 1

char *names[2] = { "/tmp/xkDeclsXXXXXX", "/tmp/xkMapsXXXXXX" };

static FILE *declFile, *mapFile;

static int
addMapPair(key, value, arg)
VOID *key, *value, *arg;
{
    long hlpId = *(long *)key;
    char *hlpName;
    
    if ((hlpName = protIdToStr(hlpId)) == 0) {
	fprintf(stderr, "ptbldump: protocol table inconsistency!  Exiting\n");
	exit(1);
    }
    fprintf(mapFile, "\t{ \"%s\", %d },\n", hlpName, *(int *)&value);
    return 1;
}

static int
doEntry(key, value, arg)
VOID *key, *value, *arg;
{
    PtblEntry *e = (PtblEntry *)value;

    /* decl file entry */
    fprintf(declFile, "\t{ \"%s\", %ld, ", e->name, e->id);
    if (e->idMap)
	fprintf(declFile, "%sMap",  e->name);
    else
	fprintf(declFile, "0");
    fprintf(declFile, " },\n");
    /* map file entry */
    if (e->idMap) {
	fprintf(mapFile, "static MapEntry %sMap[] = { \n", e->name);
	mapForEach(e->idMap, addMapPair, 0);
	fprintf(mapFile, "\t{ 0, 0 }\n");
	fprintf(mapFile, "};\n\n");
    }
    return 1;
}

static void
declPre()
{
    fprintf(declFile, "static Entry\tentries[] = {\n");
}

static void
declPost()
{
    fprintf(declFile, "\t{ 0, 0, 0 }\n");
    fprintf(declFile, "};\n");
}

static void
dumpTables()
{
    if (mktemp(names[DECL]) == 0) {
	perror("ptbldump could not get tmp name");
	exit(1);
    }
    if (mktemp(names[MAPS]) == 0) {
	perror("ptbldump could not get tmp name");
	exit(1);
    }
    if ((declFile = fopen(names[DECL], "w")) == 0) {
	perror("ptbldump could not open temp file");
	exit(1);
    }
    if ((mapFile = fopen(names[MAPS], "w")) == 0) {
	perror("ptbldump could not open temp file");
	exit(1);
    }
    declPre();
    mapForEach(ptblNameMap, doEntry, 0);
    declPost();
    fclose(mapFile);
    fclose(declFile);
    if (fork() == 0)
	execl("/bin/cat", "/bin/cat", names[MAPS], names[DECL], 0);
    wait(0);
    unlink(names[MAPS]);
    unlink(names[DECL]);
}

int
main(argc, argv)
int  argc;
char **argv;
{
    int i;
    
    prottbl_init();
    if (argc > 1) {
	for (i = 1; i < argc; i++) {
	    if (protTblBuild(argv[i])) {
		fprintf(stderr, "ptbldump -- error building protocol table\n");
		exit(1);
	    }
	}
	dumpTables();
    }
    else
	fprintf(stderr, "usage: ptbldump ptbl1 [ ptbl2 ... ]\n");
    return 0;
}

/* 
 * These stub routines are included to avoid linking in msg.c.
 */
void *msgWalkToughNext(cxt, len)
MsgWalk *cxt;
int     *len;
{ fprintf(stderr, "Remove this Stub for msgWalkToughNext!!\n"); exit(-1); }

void msgToughDestroy(n)
MsgNode n;
{ fprintf(stderr, "Remove this Stub for msgToughDestroy!!\n"); exit(-1); }
