⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nam-trace.cc

📁 ns2.1b5版本中cbrp碼
💻 CC
字号:
/* * Copyright (c) 1991,1993 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the Computer Systems *	Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used *    to endorse or promote products derived from this software without *    specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char rcsid[] ="@(#) $Header: /usr/cvs/ns/ns-src/nam/nam-trace.cc,v 1.1.1.1 1998/01/13 15:06:11 root Exp $ (LBL)";#endif#include <sys/types.h>#include <unistd.h>#include <sys/stat.h>#include <sys/file.h>#include <stdlib.h>#include <ctype.h>#include "nam-trace.h"#include "state.h"extern "C" off_t tell();extern "C" double atof();extern double time_atof(const char*);static class TraceClass : public TclClass { public:	TraceClass() : TclClass("NamTrace") {}	TclObject* create(int argc, const char*const* argv);} nam_trace_class;TclObject* TraceClass::create(int argc, const char*const* argv){	if (argc != 5)		return (0);	/*	 * Open the trace file for reading and read its first line	 * to be able to determine needed values: trace start time,	 * trace duration, etc.	 */	NamTrace* tr = new NamTrace(argv[4]);	if (!tr->valid()) {		delete tr;		/*XXX*/		tr = 0;	}	return (tr);}NamTrace::NamTrace(const char *fname) : handlers_(0){	strncpy(fileName_, fname, sizeof(fileName_)-1);	fileName_[sizeof(fileName_)-1] = 0;	int fd = open(fileName_, O_RDONLY);	if (fd < 0) {		fprintf(stderr, "nam: ");		perror(fileName_);		exit(1);	}	/*	 * Make sure the trace file isn't empty and that the last line	 * is correctly formatted. Compute the time interval for the	 * entire trace.	 */	findLastLine(fd);	file_ = fdopen(fd, "r");	if (file_ == 0) {		perror("nam: fdopen");		exit(1);	}	/*	 * Go to the beginning of the file, read the first line and	 * save its contents.	 */	rewind(0);	/*	 * Minimum time on the nam time slider is the time of the first	 * trace event.	 */	mintime_ = nextTime();	State::instance()->setTimes(mintime_, maxtime_);}int NamTrace::ReadEvent(double now, TraceEvent& e){	/*	 * If specified time is after the next event's time, read	 * the next line and return 1. Otherwise, just return 0.	 */	if (pending_.time >= 0 && pending_.time < now) {		e = pending_;		scan();		return (1);	}	return (0);}voidNamTrace::scan(){	/*	 * Read the next line in the trace file and store its contents	 * depending on line type.	 */	while (1) {		int n;				if (fgets(pending_.image, sizeof(pending_.image), file_) ==		    0) {			pending_.time = -1;			return;		}		//++lineno_;				TraceEvent& p = pending_;		char* cp = p.image;		p.offset = ftell(file_);				switch (p.tt = *cp++) {					case '#':		/* comment    */		case '\n':		/* empty line */			continue;					case 'h':		/* hop          */		case '+':		/* enqueue      */		case 'd':		/* drop line    */		case '-':		/* dequeue line */			/* <time> <hsrc> <hdst> <size> <attr> <type> <conv> <id> */			n = sscanf(cp, " %lg %d %d %d %d %7s %31s %d",				   &p.time, &p.pe.src, &p.pe.dst,				   &p.pe.pkt.size, &p.pe.pkt.attr,				   p.pe.pkt.type, p.pe.pkt.convid,				   &p.pe.pkt.id);			if (n == 8)				return;			break;					case 'v':			/*   v <time> <tcl expr> */			n = sscanf(cp, " %lg", &p.time);			if (n != 1)				break;			for (n = strlen(p.image); --n > 0; ) {				if (! isspace(p.image[n])) {					p.image[n+1] = 0;					break;				}			}			while (isspace(*cp))				++cp;			while (*cp && !isspace(*cp))				++cp;			while (isspace(*cp))				++cp;			p.ve.str = cp - p.image;			return;					default:			fprintf(stderr,				"nam: unknown event at offset %d in `%s'\n",				p.offset, fileName_);			fprintf(stderr, "nam: `%s'\n", p.image);			exit(1);		}		fprintf(stderr,			"nam: badly formatted event at offset %d in %s\n",			p.offset, fileName_);		for (n = strlen(p.image); --n > 0; ) {			if (! isspace(p.image[n])) {				p.image[n+1] = 0;				break;			}		}		fprintf(stderr, "nam: `%s'\n", p.image);		exit(1);	}	/* NOTREACHED */}/* * Go to the specified trace file's last line, verify that * the file isn't empty and that its last line is correctly * formatted. Compute the time interval for the entire trace * assuming it started at time 0. */void NamTrace::findLastLine(int fd){	char buf[257];	struct stat stat;	/* XXX	 * (?)The following doesn't move the seek pointer (it's at the	 * beginning of the file.	 */#if defined(__bsdi__) || defined(__FreeBSD__)	off_t saveseek = lseek(fd, (off_t)0, SEEK_CUR);#else	off_t saveseek = tell(fd);#endif		if (fstat(fd, &stat) < 0) {		perror("fstat");		exit(1);	}	if (stat.st_size <= 1) {		fprintf(stderr, "nam: empty trace file `%s'.", fileName_);		exit(1);	}	/*	 * If the file is larger than 'buf', go to the end of the file	 * at the point just large enough to fit into 'buf'.	 */	if (stat.st_size > sizeof(buf) - 1)		if (lseek(fd, stat.st_size + 1 - sizeof(buf), SEEK_SET) < 0) {			perror("lseek");			exit(1);		}	int n = read(fd, buf, sizeof(buf) - 1);	if (n < 0) {		perror("read");		exit(1);	}	buf[n] = 0;	/* Error if the last line doesn't have '\n' in it. */	char *cp = strrchr(buf, '\n');	if (cp == 0) {		fprintf(stderr, "nam: error reading last line of `%s'.",			fileName_);		exit(1);	}	/*	 * Look for the first '\n' and check if the line following	 * it has the correct type, i.e., it starts with any of the	 * characters in [h+-dv].	 */	*cp = 0;	cp = strrchr(buf, '\n');	if (cp == 0 || strchr("h+-dv", *++cp) == 0) {		fprintf(stderr, "nam: error reading last line of `%s'.",			fileName_);		exit(1);	}	/*	 * Compute the time interval from the beginning of the trace	 * to the end.	 * XXX this should include the duration of the last event but	 *     since we changed the format of 'size' from 'time' to	 *     'bytes', we can no longer figure this out.	 */	double time = 0.;	(void)sscanf(++cp, " %lg", &time);	maxtime_ = time;}/* Go to the beginning of the file, read the first line and process it. */void NamTrace::rewind(long offset){	fseek(file_, offset, 0);	//lineno_ = 0;	scan();}/* * Put the specified trace handler to the beginning of the trace  * handler list. */void NamTrace::addHandler(TraceHandler* th){	TraceHandlerList* p = new TraceHandlerList;	p->th = th;	p->next = handlers_;	handlers_ = p;}/* Set the current trace time to 'now'. */void NamTrace::settime(double now, int timeSliderClicked){	if (now < now_) {		for (TraceHandlerList* p = handlers_; p != 0; p = p->next)			p->th->reset(now);		StateInfo si;		State::instance()->get(now, si);		rewind(si.offset);	}	now_ = now;	/*	 * Scan the trace file until the event occurring at time 'now'	 * is read. For each event scanned, pass it on to all trace	 * handlers in the trace handler list so they can handle	 * them as needed.	 */	Tcl& tcl = Tcl::instance();	Tcl_Interp* interp = tcl.interp();	static char event[128];	TraceEvent e;	while (ReadEvent(now, e)) {		for (TraceHandlerList* p = handlers_; p != 0; p = p->next)			p->th->handle(e, now);		if (e.tt == 'h' && (e.pe.src == 0 || e.pe.dst == 0)) {			sprintf(event, "%d %d %.6f %d/", e.pe.src,				e.pe.dst, e.time, e.pe.pkt.id);			if (timeSliderClicked)				tcl.result((const char *)event);			else				Tcl_AppendResult(interp, event, 0);		}	}	for (TraceHandlerList* p = handlers_; p != 0; p = p->next)		p->th->update(now);}/* * Process 'nam trace' commands: *   mintime - return the trace start time *   maxtime - return the trace duration *   connect - add the specified trace handler to the trace handler list *   settime - reset current time to specified time and adjust the *             display as needed *   nxtevent - read next event in trace file and animate from that point */int NamTrace::command(int argc, const char*const* argv){	Tcl& tcl = Tcl::instance();	if (argc == 2) {		if (strcmp(argv[1], "mintime") == 0) {			char* bp = tcl.buffer();			sprintf(bp, "%g", mintime_);			tcl.result(bp);			return (TCL_OK);		} else if (strcmp(argv[1], "maxtime") == 0) {			char* bp = tcl.buffer();			sprintf(bp, "%g", maxtime_);			tcl.result(bp);			return (TCL_OK);		} else if (strcmp(argv[1], "nxtevent") == 0) {			char* bp = tcl.buffer();			sprintf(bp, "%g", pending_.time);			tcl.result(bp);			return (TCL_OK);		}	}	if (argc == 3) {		if (strcmp(argv[1], "connect") == 0) {			/*			 * Get the handler for the specified trace and			 * add it to the trace's list of handlers.			 */			TraceHandler* th = (TraceHandler*)TclObject::lookup(argv[2]);			if (th == 0) {				tcl.resultf("nam connect: no such trace %s",					    argv[2]);				return (TCL_ERROR);			}			addHandler(th);			return (TCL_OK);		}	}	if (argc == 4 ) {		if (strcmp(argv[1], "settime") == 0) {			/*			 * Set current time to the specified time and update			 * the display to reflect the new current time.			 */			double now = atof(argv[2]);			int timeSliderClicked = atoi(argv[3]);			settime(now, timeSliderClicked);			return (TCL_OK);		}	}	return (TclObject::command(argc, argv));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -