
/*
 *         PVM version 3.3:  Parallel Virtual Machine System
 *               University of Tennessee, Knoxville TN.
 *           Oak Ridge National Laboratory, Oak Ridge TN.
 *                   Emory University, Atlanta GA.
 *      Authors:  A. L. Beguelin, J. J. Dongarra, G. A. Geist,
 *    W. C. Jiang, R. J. Manchek, B. K. Moore, and V. S. Sunderam
 *                   (C) 1992 All Rights Reserved
 *
 *                              NOTICE
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted
 * provided that the above copyright notice appear in all copies and
 * that both the copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * Neither the Institutions (Emory University, Oak Ridge National
 * Laboratory, and University of Tennessee) nor the Authors make any
 * representations about the suitability of this software for any
 * purpose.  This software is provided ``as is'' without express or
 * implied warranty.
 *
 * PVM version 3 was funded in part by the U.S. Department of Energy,
 * the National Science Foundation and the State of Tennessee.
 */

/*
 *	tevfmt.c
 *
 *	Decode trace message.
 *
$Log: tevfmt.c,v $
 * Revision 1.3  1995/05/17  15:29:50  manchek
 * initialize sep in wuff_trace()
 *
 * Revision 1.2  1994/07/18  18:45:53  manchek
 * changed precv, psend tid to hex
 *
 * Revision 1.1  1994/06/03  20:01:53  manchek
 * Initial revision
 *
 */


#include <stdio.h>
#include "tevfmt.h"

extern char *pvm_errlist[];
extern int pvm_nerr;

struct tevfmt tev_formats[] = {
	{ "pvm_addhosts0",		"(%*d, [%$0S])" },
	{ "pvm_addhosts1",		"=%R" },
	{ "pvm_barrier0",		"(%S, %d)" },
	{ "pvm_barrier1",		"=%R" },
	{ "pvm_bcast0",			"(%S, %d)" },
	{ "pvm_bcast1",			"=%R" },
	{ "pvm_bufinfo0",		"(%d)" },
	{ "pvm_bufinfo1",		"=%R, %d, %d, %d" },
	{ "pvm_config0",		"()" },
	{ "pvm_config1",		"=%R, %d, %d" },
	{ "pvm_delete0",		"(%S, %d)" },
	{ "pvm_delete1",		"=%R" },
	{ "pvm_delhosts0",		"(%*d, [%$0S])" },
	{ "pvm_delhosts1",		"=%R" },
	{ "pvm_exit0",			"()" },
	{ "pvm_exit1",			0 },
	{ "pvm_freebuf0",		"(%d)" },
	{ "pvm_freebuf1",		"=%R" },
	{ "pvm_getfds0",		"()" },
	{ "pvm_getfds1",		"=%*R [%$0d]" },
	{ "pvm_getinst0",		"(%S, %d)" },
	{ "pvm_getinst1",		"=%R" },
	{ "pvm_getopt0",		"(%d)" },
	{ "pvm_getopt1",		"=%R" },
	{ "pvm_getrbuf0",		"()" },
	{ "pvm_getrbuf1",		"=%R" },
	{ "pvm_getsbuf0",		"()" },
	{ "pvm_getsbuf1",		"=%R" },
	{ "pvm_gettid0",		"(%S, %d)" },
	{ "pvm_gettid1",		"=%R" },
	{ "pvm_gsize0",			"(%S)" },
	{ "pvm_gsize1",			"=%R" },
	{ "pvm_halt0",			"()" },
	{ "pvm_halt1",			0 },
	{ "pvm_initsend0",		"(%d)" },
	{ "pvm_initsend1",		"=%R" },
	{ "pvm_insert0",		"(%S, %d, %x)" },
	{ "pvm_insert1",		"=%R" },
	{ "pvm_joingroup0",		"(%S)" },
	{ "pvm_joingroup1",		"=%R" },
	{ "pvm_kill0",			"(%x)" },
	{ "pvm_kill1",			"=%R" },
	{ "pvm_lookup0",		"(%S, %d)" },
	{ "pvm_lookup1",		"=%R" },
	{ "pvm_lvgroup0",		"(%S)" },
	{ "pvm_lvgroup1",		"=%R" },
	{ "pvm_mcast0",			"(%*d, %d, [%$0x])" },
	{ "pvm_mcast1",			"=%R" },
	{ "pvm_mkbuf0",			"(%d)" },
	{ "pvm_mkbuf1",			"=%R" },
	{ "pvm_mstat0",			"(%S)" },
	{ "pvm_mstat1",			"=%R" },
	{ "pvm_mytid0",			"()" },
	{ "pvm_mytid1",			"=%r" },
	{ "pvm_notify0",		"(%d, %d, %d, ...)" },
	{ "pvm_notify1",		"=%R" },
	{ "pvm_nrecv0",			"(%x, %d)" },
	{ "pvm_nrecv1",			"=%R, ..." },
	{ "pvm_parent0",		"()" },
	{ "pvm_parent1",		"=%r" },
	{ "pvm_perror0",		"(%S %d)" },
	{ "pvm_perror1",		0 },
	{ "pvm_pkbyte0",		"(%x, %d, %d)" },
	{ "pvm_pkbyte1",		"=%R" },
	{ "pvm_pkcplx0",		"(%x, %d, %d)" },
	{ "pvm_pkcplx1",		"=%R" },
	{ "pvm_pkdcplx0",		"(%x, %d, %d)" },
	{ "pvm_pkdcplx1",		"=%R" },
	{ "pvm_pkdouble0",		"(%x, %d, %d)" },
	{ "pvm_pkdouble1",		"=%R" },
	{ "pvm_pkfloat0",		"(%x, %d, %d)" },
	{ "pvm_pkfloat1",		"=%R" },
	{ "pvm_pkint0",			"(%x, %d, %d)" },
	{ "pvm_pkint1",			"=%R" },
	{ "pvm_pkuint0",		"(%x, %d, %d)" },
	{ "pvm_pkuint1",		"=%R" },
	{ "pvm_pklong0",		"(%x, %d, %d)" },
	{ "pvm_pklong1",		"=%R" },
	{ "pvm_pkulong0",		"(%x, %d, %d)" },
	{ "pvm_pkulong1",		"=%R" },
	{ "pvm_pkshort0",		"(%x, %d, %d)" },
	{ "pvm_pkshort1",		"=%R" },
	{ "pvm_pkushort0",		"(%x, %d, %d)" },
	{ "pvm_pkushort1",		"=%R" },
	{ "pvm_pkstr0",			"(%x)" },
	{ "pvm_pkstr1",			"=%R" },
	{ "pvm_probe0",			"(%x, %d)" },
	{ "pvm_probe1",			"=%R" },
	{ "pvm_pstat0",			"(%x)" },
	{ "pvm_pstat1",			"=%R" },
	{ "pvm_recv0",			"(%x, %d)" },
	{ "pvm_recv1",			"=%R, %d, ..." },
	{ "pvm_recvf0",			"(...)" },
	{ "pvm_recvf1",			0 },
	{ "pvm_send0",			"(%x, %d)" },
	{ "pvm_send1",			"=%R" },
	{ "pvm_sendsig0",		"(%x, %d)" },
	{ "pvm_sendsig1",		"=%R" },
	{ "pvm_setopt0",		"(%d, %d)" },
	{ "pvm_setopt1",		"=%R" },
	{ "pvm_setrbuf0",		"(%d)" },
	{ "pvm_setrbuf1",		"=%R" },
	{ "pvm_setsbuf0",		"(%d)" },
	{ "pvm_setsbuf1",		"=%R" },
	{ "pvm_spawn0",			"(%S, ?, %d, %S, %d, ...)" },
	{ "pvm_spawn1",			"=%*R [%$0r]" },
	{ "pvm_start_pvmd0","%d, %d, ..." },
	{ "pvm_start_pvmd1","=%R" },
	{ "pvm_tasks0",			"(%x)" },
	{ "pvm_tasks1",			"=%R, %d" },
	{ "pvm_tickle0",		"(%*d, [%$0d])" },
	{ "pvm_tickle1",		"=%R, %d" },
	{ "pvm_tidtohost0",		"(%x)" },
	{ "pvm_tidtohost1",		"=%r" },
	{ "pvm_trecv0",			"(%x, %d, [%d %d])" },
	{ "pvm_trecv1",			"=%R, %d, ..." },
	{ "pvm_upkbyte0",		"(%x, %d, %d)" },
	{ "pvm_upkbyte1",		"=%R" },
	{ "pvm_upkcplx0",		"(%x, %d, %d)" },
	{ "pvm_upkcplx1",		"=%R" },
	{ "pvm_upkdcplx0",		"(%x, %d, %d)" },
	{ "pvm_upkdcplx1",		"=%R" },
	{ "pvm_upkdouble0",		"(%x, %d, %d)" },
	{ "pvm_upkdouble1",		"=%R" },
	{ "pvm_upkfloat0",		"(%x, %d, %d)" },
	{ "pvm_upkfloat1",		"=%R" },
	{ "pvm_upkint0",		"(%x, %d, %d)" },
	{ "pvm_upkint1",		"=%R" },
	{ "pvm_upkuint0",		"(%x, %d, %d)" },
	{ "pvm_upkuint1",		"=%R" },
	{ "pvm_upklong0",		"(%x, %d, %d)" },
	{ "pvm_upklong1",		"=%R" },
	{ "pvm_upkulong0",		"(%x, %d, %d)" },
	{ "pvm_upkulong1",		"=%R" },
	{ "pvm_upkshort0",		"(%x, %d, %d)" },
	{ "pvm_upkshort1",		"=%R" },
	{ "pvm_upkushort0",		"(%x, %d, %d)" },
	{ "pvm_upkushort1",		"=%R" },
	{ "pvm_upkstr0",		"(%x)" },
	{ "pvm_upkstr1",		"=%R" },
	{ "pvm_version0",		"()" },
	{ "pvm_version1",		"=%S" },
	{ "pvm_reg_hoster0",	"()" },
	{ "pvm_reg_hoster1",	"=%R" },
	{ "pvm_reg_rm0",		"()" },
	{ "pvm_reg_rm1",		"=%R" },
	{ "pvm_reg_tasker0",	"()" },
	{ "pvm_reg_tasker1",	"=%R" },
	{ "newtask",			" %x, %d, %S" },
	{ "",					0 },
	{ "endtask",			" %x u %d,%d s %d,%d" },
	{ "",					0 },
	{ "spntask",			" %x" },
	{ "",					0 },
	{ "pvm_archcode0",		0 /*"(%S)"*/ },
	{ "pvm_archcode1",		0 /*"=%R"*/ },
	{ "pvm_catchout0",		0 /*"(...)"*/ },
	{ "pvm_catchout1",		0 /*"=%R"*/ },
	{ "pvm_getmwid0",		"(%d)" },
	{ "pvm_getmwid1",		"=%R" },
	{ "pvm_gettmask0",		0 /*"(%d, )"*/ },
	{ "pvm_gettmask1",		0 /*"=%R"*/ },
	{ "pvm_hostsync0",		0 /*"(%d, ...)"*/ },
	{ "pvm_hostsync1",		0 /*"=%R"*/ },
	{ "pvm_packf0",			"(%S, ...)" },
	{ "pvm_packf1",			"=%R" },
	{ "pvm_precv0",			"(%x, %d, %x, %d, %d, ...)" },
	{ "pvm_precv1",			"=%R" },
	{ "pvm_psend0",			"(%x, %d, %x, %d, %d)" },
	{ "pvm_psend1",			"=%R" },
	{ "pvm_reduce0",		0 /*"(...)"*/ },
	{ "pvm_reduce1",		0 /*"=%R"*/ },
	{ "pvm_setmwid0",		"(%d, %d)" },
	{ "pvm_setmwid1",		"=%R" },
	{ "pvm_settmask0",		0 /*"(%d, %S)"*/ },
	{ "pvm_settmask1",		0 /*"=%R"*/ },
	{ "pvm_unpackf0",		"(%S, ...)" },
	{ "pvm_unpackf1",		"=%R" },
	{ "pvm_gather0",		0 },
	{ "pvm_gather1",		0 },
	{ "pvm_scatter0",		0 },
	{ "pvm_scatter1",		0 },
};


/*	wuff_trace()
*
*	Unpack trace event from message and wuff it to a FILE* .
*/

int
wuff_trace(ff, kind)
	FILE *ff;
	int kind;
{
	int ival;			/* int result value */
	int keep;			/* keep result on kplist */
	int kplist[10];		/* list of result counts */
	int nk = 0;			/* length of kplist */
	int vl;				/* length of result vector */
	int vflg;			/* result is dynamic vector */
	int i;
	char *s;			/* format */
	char sep = 0;
	char buf[4096];

	if (kind < 0 || kind > sizeof(tev_formats)/sizeof(tev_formats[0])) {
		fputs("?", ff);
		return 1;
	}

	fprintf(ff, "%s", tev_formats[kind].name);
	s = tev_formats[kind].fmt;

	if (!s)
		s = "";

	while (*s) {
		if (*s == '%') {
			s++;

			if (*s == '*') {
				keep = 1;
				s++;
			} else
				keep = 0;

			if (*s == '$') {
				s++;
				i = *s - '0';
				vl = (i >= 0 && i < nk) ? kplist[i] : 0;
				vflg = 1;
				s++;
				sep = 0;

			} else {
				vl = 1;
				vflg = 0;
			}

			while (vl-- > 0) {
				if (vflg) {
					if (sep)
						putc(sep, ff);
					sep = ' ';
				}
				switch (*s) {

				case 'd':
					pvm_upkint(&ival, 1, 1);
					fprintf(ff, "%d", ival);
					break;

				case 'R':	/* decimal result code */
					pvm_upkint(&ival, 1, 1);
					fprintf(ff, "%d", ival);
					if (ival < 0)
						fprintf(ff, " (%s)",
								(ival <= 0 && ival > -pvm_nerr
								? pvm_errlist[-ival] : "Unknown Error"));
					break;

				case 'r':	/* hex result code / decimal if negative */
					pvm_upkint(&ival, 1, 1);
					if (ival < 0)
						fprintf(ff, "%d (%s)", ival,
								(ival <= 0 && ival > -pvm_nerr
								? pvm_errlist[-ival] : "Unknown Error"));
					else
						fprintf(ff, "0x%x", ival);
					break;

				case 'x':
					pvm_upkint(&ival, 1, 1);
					fprintf(ff, "0x%x", ival);
					break;

				case 'S':
					pvm_upkstr(buf);
					fprintf(ff, "\"%s\"", buf);
					break;

				default:
					putc('%', ff);
					putc(*s, ff);
					break;
				}
			}

			if (*s)
				s++;

			if (keep) {
				kplist[nk++] = ival < 0 ? 0 : ival;
			}

		} else {
			putc(*s, ff);
			s++;
		}
	}
	return 0;
}



