parser.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:40k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1997-2001 University of Southern California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *      This product includes software developed by the Information Sciences
  16.  *      Institute of the University of Southern California.
  17.  * 4. Neither the name of the University nor of the Institute may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  */
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #include <ctype.h>
  37. #include "parser.h"
  38. #include "trace.h"
  39. //----------------------------------------------------------------------
  40. //
  41. //----------------------------------------------------------------------
  42. Attribute::Attribute(char _flag, void * _value_ptr, char * _value_type,
  43.                      char * _default_value, bool _required, char * _label) {
  44.   flag = _flag;
  45.   value_ptr = _value_ptr;
  46.   other_ptr = NULL;
  47.   value_type = _value_type;
  48.   default_value = _default_value;
  49.   required = _required;
  50.   seen = false;
  51.   label = _label;
  52.   next = NULL;  
  53. }
  54. //----------------------------------------------------------------------
  55. //
  56. //----------------------------------------------------------------------
  57. char * 
  58. Attribute::parseValue(char * run, char * line) {
  59.   char buffer[MAXVALUE];
  60.   double angle;
  61.   if (!strcmp(value_type, "int")) {
  62.     *((int *) value_ptr) = atoi(run);
  63.     run = advanceToSpace(run);
  64.   } else if (!strcmp(value_type, "double")) {
  65.     *((double *) value_ptr) = atof(run);
  66.     run = advanceToSpace(run);
  67.   } else if (!strcmp(value_type, "string") || 
  68.              !strcmp(value_type, "hex")) {
  69.     run = extractString(run,(char *) value_ptr);
  70.   } else if (!strcmp(value_type, "string l")) {
  71.     run = extractString(run, buffer);
  72.     // Check for use as length in link event
  73.     if (other_ptr && isdigit(buffer[0])) {
  74.       fprintf(stderr, "Nam syntax has changed: %sPlease use -h instead of -l for length.nn",line);
  75.       *((double *) other_ptr) = atof(buffer);
  76.     } else {
  77.       strcpy((char *) value_ptr, buffer);
  78.     }
  79.   } else if (!strcmp(value_type, "color")) {
  80.     // Checking for angle to be bacwards compatible
  81.     // with the -o flag standing for orientation
  82.     run = extractString(run, buffer);
  83.     angle = determineAngle(buffer);
  84.     if (angle == -1.0) {
  85.      // We must have a color
  86.      strcpy((char *) value_ptr, buffer); 
  87.     } else { 
  88.       if (other_ptr) {
  89.         fprintf(stderr, "Nam syntax has changed: %sPlease use -O instead of -o for orientation.nn",line);
  90.         *((double *) other_ptr) = angle;
  91.       }
  92.     }
  93.   } else if (!strcmp(value_type, "time")) {
  94.     if (*run == '*') {
  95.       *((double *) value_ptr) = 0.0;
  96.       run++;
  97.     } else {
  98.       *((double *) value_ptr) = atof(run);
  99.       run = advanceToSpace(run);
  100.     }
  101.   } else if (!strcmp(value_type, "comment")) {
  102.     if (*run == '{') {
  103.       run++;
  104.       // Grab first value (Source)
  105.       ((PacketAttr *)value_ptr)->esrc = atoi(run);
  106.       // Grab second value (Destination)
  107.       run = advanceToSpace(run); 
  108.       run = eatSpaces(run);
  109.       ((PacketAttr *) value_ptr)->edst = atoi(run);
  110.       // Eat the rest of the comment
  111.       while (*run != '}' && *run != 'n') {
  112.         run++;
  113.       }
  114.       // Eat last curly brace
  115.       if (*run == '}') {
  116.         run++;
  117.       }
  118.     } else {
  119.       fprintf(stderr, "Error in comment field: %sn", line);
  120.     }
  121.   } else if (!strcmp(value_type, "flag")) {
  122.     if (*run == '-' || *run == '' || isspace(*run)) {
  123.       // For cases where the flag is -x followed by another attribute  
  124.       // or on the end of the line.  If -x is followed by another attribute
  125.       // run should point to - in -n 1
  126.       // For example -x -n 1 or -x or -n 1 -xn
  127.       *((int *) value_ptr) = 1;
  128.     } else if (isdigit(*run)) {
  129.       // For intialization cases or when you get -x 2 
  130.       *((int *) value_ptr) = atoi(run);
  131.       run = advanceToSpace(run); 
  132.     } else {
  133.       // The syntax is really messed up so report an
  134.       // error and skip over the value
  135.       fprintf(stderr, "Invalid value for flag attribute type in line: %sn",line);
  136.       run = advanceToSpace(run);
  137.     }
  138.   } else if (!strcmp(value_type, "char")) {
  139.     *((char *) value_ptr) = *run;
  140.     run = advanceToSpace(run);
  141.   } else if (!strcmp(value_type, "orientation")) {
  142.     run = extractString(run, buffer);
  143.     angle = determineAngle(buffer);
  144.     if (angle == -1.0) {
  145.      angle = 0.0;
  146.     } 
  147.     *((double *) value_ptr) = angle;
  148.     
  149.   } else if (!strcmp(value_type, "packet source")) {
  150.     if (*run == '*') {
  151.       *((int *) value_ptr) = -1;
  152.       run++;
  153.     } else {
  154.       *((int *) value_ptr) = atoi(run);
  155.       run = advanceToSpace(run);
  156.     }
  157.   } else if (!strcmp(value_type, "shape")) {
  158.     run = extractString(run, buffer);
  159.     // Check for being used as y_vel_ in old nam
  160.     // syntax
  161.     if (isdigit(buffer[0]) || (buffer[0] == '-' && isdigit(buffer[1]))) {
  162.       if (other_ptr) {
  163.         fprintf(stderr, "Nam syntax has changed: %sPlease use -V instead of -v for y velocity nn",line);
  164.         *((double *) other_ptr) = atof(buffer);
  165.       }
  166.     } else {
  167.       strcpy((char *) value_ptr, buffer); 
  168.     }
  169.   } else if (!strcmp(value_type, "tcl expression")) {
  170.     //*((char **) value_ptr) = run;
  171.     *((int *) value_ptr) = run - line;
  172.     
  173.     //Advance to next flag or end of line
  174.     run = advanceToEndofLine(run);
  175.   }
  176.   return run;
  177. }
  178. //----------------------------------------------------------------------
  179. //
  180. //----------------------------------------------------------------------
  181. void
  182. Attribute::setDefaultValue() {
  183.   parseValue(default_value, default_value);
  184. }
  185. //----------------------------------------------------------------------
  186. //  double
  187. //  Attribute::determineAngle(char * buffer)
  188. //      - Determines angle based on up-right, up, down, down-left, etc
  189. //        constants.  Also will try to extract a numeric angle from buffer
  190. //        if unable to determine angle -1 is returned
  191. //----------------------------------------------------------------------
  192. double
  193. Attribute::determineAngle(char * buffer) {
  194.   double angle;
  195.   if (isalpha(*buffer) || *buffer == '"' || *buffer == '#') {
  196.     // Set angle based on constants
  197.     if (!strcmp(buffer, "right")) {
  198.       angle = 0.0;
  199.     } else if (!strcmp(buffer, "up-right") || !strcmp(buffer, "right-up")) {
  200.       angle = 0.25;
  201.     } else if (!strcmp(buffer, "up")) {
  202.       angle = 0.50;
  203.     } else if (!strcmp(buffer, "up-left") || !strcmp(buffer, "left-up")) {
  204.       angle = 0.75;
  205.     } else if (!strcmp(buffer, "left")) {
  206.       angle = 1.0;
  207.     } else if (!strcmp(buffer, "left-down") || !strcmp(buffer, "down-left")) {
  208.       angle = 1.25;
  209.     } else if (!strcmp(buffer, "down")) {
  210.       angle = 1.50;
  211.     } else if (!strcmp(buffer, "down-right") || !strcmp(buffer, "right-down")) {
  212.       angle = 1.75;
  213.     } else {
  214.      angle = -1.0;
  215.     } 
  216.   } else {
  217.     angle = atof(buffer);
  218.   }
  219.   return angle;
  220. }
  221. //----------------------------------------------------------------------
  222. //
  223. //----------------------------------------------------------------------
  224. TraceSyntax::TraceSyntax(char event_id, char * _label) {
  225.   type = event_id;
  226.   label = _label;
  227.   attributes = NULL;
  228.   last_attribute = NULL;
  229.   total_required_attributes = 0;
  230.   number_of_attributes = 0;
  231.   next = NULL;
  232. }
  233. //----------------------------------------------------------------------
  234. //
  235. //----------------------------------------------------------------------
  236. Attribute * 
  237. TraceSyntax::addAttribute(char flag, void * value_ptr, char * type,
  238.                           char * default_value, bool required,
  239.                           char * label) {
  240.   Attribute * attribute = new Attribute(flag, value_ptr, type,
  241.                                         default_value, required, label);
  242.   if (attribute) {
  243.     // Add attribute to list of attributes for this ParseTraceSyntax
  244.     if (!attributes) {
  245.       attributes = attribute;
  246.       last_attribute = attribute;
  247.     } else {
  248.       last_attribute->next = attribute;
  249.       last_attribute = attribute;
  250.     }
  251.     number_of_attributes++;
  252.     if (required) {
  253.       total_required_attributes++;
  254.     }
  255.   }
  256.   return attribute;
  257. }
  258. //----------------------------------------------------------------------
  259. //  Attribute * 
  260. //  TraceSyntax::addAttribute(char flag, void * value_ptr, char * type,
  261. //                            char * default_value, bool required,
  262. //                            char * label, void * other_ptr) 
  263. //
  264. //   - other_ptr is a pointer to an alternate location to put data.
  265. //     It is used to enable backwards compatability with the old
  266. //     nam syntax.
  267. //----------------------------------------------------------------------
  268. Attribute * 
  269. TraceSyntax::addAttribute(char flag, void * value_ptr, char * type,
  270.                           char * default_value, bool required,
  271.                           char * label, void * other_ptr) {
  272.   Attribute * attribute;
  273.   attribute = addAttribute(flag, value_ptr, type, default_value, required, label);
  274.   if (attribute) {
  275.    attribute->other_ptr = other_ptr;
  276.   }
  277.   return attribute; 
  278. }
  279. //----------------------------------------------------------------------
  280. //
  281. //----------------------------------------------------------------------
  282. void
  283. TraceSyntax::setDefaultAttributeValues() {
  284.   Attribute * attribute = attributes;
  285.   while (attribute) {
  286.     attribute->setDefaultValue();
  287.     attribute->seen = false;
  288.     attribute = attribute->next;
  289.   }
  290. }
  291. //----------------------------------------------------------------------
  292. //
  293. //----------------------------------------------------------------------
  294. //<zheng: +++>
  295. bool ParseTable::nam4wpan = false;
  296. int ParseTable::wpan_bradius = -1;
  297. //</zheng: +++>
  298. ParseTable::ParseTable(TraceEvent * _pending) {
  299.   TraceSyntax * ts;
  300.   
  301.   syntax_list = NULL;
  302.   syntax_list_tail = NULL;
  303.   pending = _pending;
  304.   // Comment
  305.   ts = addTraceSyntax('#', "comment -- this line is ignored");
  306.   // Time sync dummy event
  307.   ts = addTraceSyntax('T', "Dummy event to be used in time synchronization");
  308.   ts->addAttribute('t', &pending->time, "time", "-1.0", true, "time");
  309.   // ---- Node ----
  310.   // Wireless node stuff seems to be wierd.
  311.   // A lot of the code dealing with wireless bases decisions on number of attributes
  312.   // and not a wireless attribute flag. 
  313.   ts = addTraceSyntax('n', "node");
  314.   ts->addAttribute('t', &pending->time, "time", "-1.0", true, "time");
  315.   ts->addAttribute('s', &pending->ne.src, "int", "-1", true, "node id"); 
  316.   ts->addAttribute('u', &pending->ne.x_vel_, "double", "0.0", false, "x velocity");
  317.   ts->addAttribute('U', &pending->ne.x_vel_, "double", "0.0", false, "x velocity");
  318.   ts->addAttribute('V', &pending->ne.y_vel_, "double", "0.0", false, "y velocity");
  319.   // old nam syntax allowed for -v to also mean y velocity
  320.   ts->addAttribute('v', &pending->ne.mark.shape, "shape", "circle", false, "shape (circle, box, hexagon)", &pending->ne.y_vel_);
  321.   ts->addAttribute('c', &pending->ne.node.color, "color", "black", false, "color"); 
  322.   ts->addAttribute('z', &pending->ne.size, "double", "10.0", false, "size of node"); 
  323.   ts->addAttribute('a', &pending->ne.node.addr, "int", "0", false, "address"); 
  324.   ts->addAttribute('x', &pending->ne.x, "double", "0.0", false, "x location"); 
  325.   ts->addAttribute('y', &pending->ne.y, "double", "0.0", false, "y location"); 
  326.   ts->addAttribute('Z', &pending->ne.z, "double", "0.0", false, "z location (not supported)"); 
  327.   ts->addAttribute('i', &pending->ne.node.lcolor, "color", "black", false, "label color");
  328.   ts->addAttribute('b', &pending->ne.node.dlabel, "string", "", false, "label"); // Initialization
  329.   ts->addAttribute('l', &pending->ne.node.dlabel, "string", "", false, "label");
  330.   ts->addAttribute('o', &pending->ne.node.oldColor, "color", "gray", false, "previous color");
  331.   ts->addAttribute('S', &pending->ne.node.state, "string", "UP", false, "state (UP, DOWN, COLOR)");
  332.   ts->addAttribute('L', &pending->ne.node.odlabel, "string", "", false, "previous label");
  333.   ts->addAttribute('p', &pending->ne.node.direction, "string", "", false, "label location");
  334.   ts->addAttribute('P', &pending->ne.node.odirection, "string", "", false, "previous label location");
  335.   ts->addAttribute('i', &pending->ne.node.lcolor, "color", "black", false, "inside label color");
  336.   ts->addAttribute('I', &pending->ne.node.olcolor, "color", "black", false, "previous inside label color");
  337.   ts->addAttribute('e', &pending->ne.node.dcolor, "color", "black", false, "label color");
  338.   ts->addAttribute('E', &pending->ne.node.odcolor, "color", "black", false, "previous label color");
  339.   ts->addAttribute('T', &pending->ne.stoptime, "double", "0.0", false, "duration of movement");
  340.   ts->addAttribute('w', &pending->ne.wireless, "flag", "0", false, "wireless node");
  341.   // ---- Link ----
  342.   ts = addTraceSyntax('l', "link");
  343.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  344.   ts->addAttribute('s', &pending->le.src, "int", "-1", true, "source id"); 
  345.   ts->addAttribute('d', &pending->le.dst, "int", "-1", true, "destination id"); 
  346.   ts->addAttribute('r', &pending->le.link.rate, "double", "1.0", false, "transmission rate"); 
  347.   ts->addAttribute('D', &pending->le.link.delay, "double", "1.0", false, "delay"); 
  348.   ts->addAttribute('h', &pending->le.link.length, "double", "1.0", false, "length"); 
  349.   ts->addAttribute('O', &pending->le.link.angle, "orientation", "1.0", false, "orientation"); 
  350.   ts->addAttribute('b', &pending->le.link.dlabel, "string", "", false, "label");
  351.   ts->addAttribute('c', &pending->le.link.color, "color", "black", false, "color");
  352.   // old nam syntax allowed for 'o' to be color or orientation
  353.   ts->addAttribute('o', &pending->le.link.oldColor, "color", "gray", false, "previous color", &pending->le.link.angle);  
  354.   ts->addAttribute('S', &pending->le.link.state, "string", "UP", true, "state (UP, DOWN)"); 
  355.   // old nam syntax allowed for 'l' to be length or label
  356.   ts->addAttribute('l', &pending->le.link.dlabel, "string l", "", false, "label", &pending->le.link.length); 
  357.   ts->addAttribute('L', &pending->le.link.odlabel, "string", "", false, "previous label"); 
  358.   ts->addAttribute('e', &pending->le.link.dcolor, "color", "", false, "label color"); 
  359.   ts->addAttribute('E', &pending->le.link.odcolor, "color", "", false, "previous label color"); 
  360.   
  361.   // ---- Enqueue Packet ----
  362.   ts = addTraceSyntax('+', "enqueue packet");
  363.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  364.   ts->addAttribute('s', &pending->pe.src, "int", "-1", true, "source id"); 
  365.   ts->addAttribute('d', &pending->pe.dst, "int", "-1", true, "destination id"); 
  366.   ts->addAttribute('e', &pending->pe.pkt.size, "int", "1", false, "extent"); 
  367.   ts->addAttribute('a', &pending->pe.pkt.attr, "int", "0", false, "packet color attribute id"); 
  368.   ts->addAttribute('i', &pending->pe.pkt.id, "int", "0", false, "id"); 
  369.   ts->addAttribute('l', &pending->pe.pkt.energy, "int", "0", false, "energy"); 
  370.   ts->addAttribute('c', &pending->pe.pkt.convid, "string", "", false, "conversation"); 
  371.   ts->addAttribute('x', &pending->pe.pkt, "comment", "{-1 -1 }", false, "comment"); 
  372.   ts->addAttribute('p', &pending->pe.pkt.type, "string", "", false, "packet type"); 
  373.   ts->addAttribute('k', &pending->pe.pkt.wtype, "string", "", false, "packet type"); 
  374.   ts->addAttribute('y', &pending->pe.namgraph_flags, "comment", "{0 0}", false, "");
  375.   ts->addAttribute('S', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  376.   ts->addAttribute('m', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  377.   ts->addAttribute('f', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  378.    
  379.   // ---- Dequeue Packet ----
  380.   ts = addTraceSyntax('-', "dequeue packet");
  381.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  382.   ts->addAttribute('s', &pending->pe.src, "int", "-1", true, "source id"); 
  383.   ts->addAttribute('d', &pending->pe.dst, "int", "-1", true, "destination id"); 
  384.   ts->addAttribute('e', &pending->pe.pkt.size, "int", "1", false, "extent"); 
  385.   ts->addAttribute('a', &pending->pe.pkt.attr, "int", "0", false, "attribute"); 
  386.   ts->addAttribute('i', &pending->pe.pkt.id, "int", "0", false, "id"); 
  387.   ts->addAttribute('l', &pending->pe.pkt.energy, "int", "0", false, "energy"); 
  388.   ts->addAttribute('c', &pending->pe.pkt.convid, "string", "", false, "conversation"); 
  389.   ts->addAttribute('x', &pending->pe.pkt, "comment", "{-1 -1 }", false, "comment"); 
  390.   ts->addAttribute('p', &pending->pe.pkt.type, "string", "", false, "packet type"); 
  391.   ts->addAttribute('k', &pending->pe.pkt.wtype, "string", "", false, "packet type"); 
  392.   ts->addAttribute('y', &pending->pe.namgraph_flags, "comment", "{0 0}", false, "");
  393.   ts->addAttribute('S', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  394.   ts->addAttribute('m', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  395.   ts->addAttribute('f', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  396.   // ---- Hop ----
  397.   ts = addTraceSyntax('h', "hop");
  398.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  399.   ts->addAttribute('s', &pending->pe.src, "int", "-1", true, "source id"); 
  400.   ts->addAttribute('d', &pending->pe.dst, "int", "-1", true, "destination id"); 
  401.   ts->addAttribute('e', &pending->pe.pkt.size, "int", "1", false, "extent"); 
  402.   ts->addAttribute('a', &pending->pe.pkt.attr, "int", "0", false, "attribute"); 
  403.   ts->addAttribute('i', &pending->pe.pkt.id, "int", "0", false, "id"); 
  404.   ts->addAttribute('l', &pending->pe.pkt.energy, "int", "0", false, "energy"); 
  405.   ts->addAttribute('c', &pending->pe.pkt.convid, "string", "", false, "conversation"); 
  406.   ts->addAttribute('x', &pending->pe.pkt, "comment", "{-1 -1 }", false, "comment"); 
  407.   ts->addAttribute('p', &pending->pe.pkt.type, "string", "", false, "packet type"); 
  408.   ts->addAttribute('k', &pending->pe.pkt.wtype, "string", "", false, "packet type"); 
  409.   ts->addAttribute('y', &pending->pe.namgraph_flags, "comment", "{0 0}", false, "");
  410.   ts->addAttribute('S', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  411.   ts->addAttribute('m', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  412.   ts->addAttribute('f', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  413.   ts->addAttribute('R', &pending->pe.pkt.wBcastRadius, "double", "0", false, "wireless broadcast radius");
  414.   ts->addAttribute('D', &pending->pe.pkt.wBcastDuration, "double", "0", false, "wireless broadcast duration");
  415.    
  416.   // ---- Receive ----
  417.   ts = addTraceSyntax('r', "receive");
  418.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  419.   ts->addAttribute('s', &pending->pe.src, "int", "-1", true, "source id"); 
  420.   ts->addAttribute('d', &pending->pe.dst, "int", "-1", true, "destination id"); 
  421.   ts->addAttribute('e', &pending->pe.pkt.size, "int", "1", false, "extent"); 
  422.   ts->addAttribute('a', &pending->pe.pkt.attr, "int", "0", false, "attribute"); 
  423.   ts->addAttribute('i', &pending->pe.pkt.id, "int", "0", false, "id"); 
  424.   ts->addAttribute('l', &pending->pe.pkt.energy, "int", "0", false, "energy"); 
  425.   ts->addAttribute('c', &pending->pe.pkt.convid, "string", "", false, "conversation"); 
  426.   ts->addAttribute('x', &pending->pe.pkt, "comment", "{-1 -1 }", false, "comment"); 
  427.   ts->addAttribute('p', &pending->pe.pkt.type, "string", "", false, "packet type"); 
  428.   ts->addAttribute('k', &pending->pe.pkt.wtype, "string", "", false, "packet type"); 
  429.   ts->addAttribute('y', &pending->pe.namgraph_flags, "comment", "{0 0}", false, "");
  430.   ts->addAttribute('S', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  431.   ts->addAttribute('m', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  432.   ts->addAttribute('f', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  433.   ts->addAttribute('R', &pending->pe.pkt.wBcastRadius, "double", "0", false, "wireless broadcast radius");
  434.   ts->addAttribute('D', &pending->pe.pkt.wBcastDuration, "double", "0", false, "wireless broadcast duration");
  435.    
  436.   // ---- Drop Line ----
  437.   ts = addTraceSyntax('d', "drop line");
  438.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  439.   ts->addAttribute('s', &pending->pe.src, "int", "-1", true, "source id"); 
  440.   ts->addAttribute('d', &pending->pe.dst, "int", "-1", true, "destination id"); 
  441.   ts->addAttribute('e', &pending->pe.pkt.size, "int", "1", false, "extent"); 
  442.   ts->addAttribute('a', &pending->pe.pkt.attr, "int", "0", false, "attribute"); 
  443.   ts->addAttribute('i', &pending->pe.pkt.id, "int", "0", false, "id"); 
  444.   ts->addAttribute('l', &pending->pe.pkt.energy, "int", "0", false, "energy"); 
  445.   ts->addAttribute('c', &pending->pe.pkt.convid, "string", "", false, "conversation"); 
  446.   ts->addAttribute('x', &pending->pe.pkt, "comment", "{-1 -1 }", false, "comment"); 
  447.   ts->addAttribute('p', &pending->pe.pkt.type, "string", "", false, "packet type"); 
  448.   ts->addAttribute('k', &pending->pe.pkt.wtype, "string", "", false, "packet type"); 
  449.   ts->addAttribute('y', &pending->pe.namgraph_flags, "comment", "{0 0}", false, "");
  450.   ts->addAttribute('S', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  451.   ts->addAttribute('m', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  452.   ts->addAttribute('f', &pending->pe.namgraph_flags.size, "int", "0", false, "");
  453.    
  454.   // ---- Session Enqueue ----
  455.   ts = addTraceSyntax('E', "session enqueue");
  456.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  457.   ts->addAttribute('s', &pending->pe.src, "int", "-1", true, "source id"); 
  458.   ts->addAttribute('d', &pending->pe.dst, "int", "-1", true, "destination id"); 
  459.   ts->addAttribute('e', &pending->pe.pkt.size, "int", "1", false, "extent"); 
  460.   ts->addAttribute('a', &pending->pe.pkt.attr, "int", "0", false, "attribute"); 
  461.   ts->addAttribute('i', &pending->pe.pkt.id, "int", "0", false, "id"); 
  462.   ts->addAttribute('l', &pending->pe.pkt.energy, "int", "0", false, "energy"); 
  463.   ts->addAttribute('c', &pending->pe.pkt.convid, "string", "", false, "conversation"); 
  464.   ts->addAttribute('x', &pending->pe.pkt, "comment", "{-1 -1 }", false, "comment"); 
  465.   ts->addAttribute('p', &pending->pe.pkt.type, "string", "", false, "packet type"); 
  466.   ts->addAttribute('k', &pending->pe.pkt.wtype, "string", "", false, "packet type"); 
  467.    
  468.   // ---- session dequeue ----
  469.   ts = addTraceSyntax('D', "session dequeue");
  470.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  471.   ts->addAttribute('s', &pending->pe.src, "int", "-1", true, "source id"); 
  472.   ts->addAttribute('d', &pending->pe.dst, "int", "-1", true, "destination id"); 
  473.   ts->addAttribute('e', &pending->pe.pkt.size, "int", "1", false, "extent"); 
  474.   ts->addAttribute('a', &pending->pe.pkt.attr, "int", "0", false, "attribute"); 
  475.   ts->addAttribute('i', &pending->pe.pkt.id, "int", "0", false, "id"); 
  476.   ts->addAttribute('l', &pending->pe.pkt.energy, "int", "0", false, "energy"); 
  477.   ts->addAttribute('c', &pending->pe.pkt.convid, "string", "", false, "conversation"); 
  478.   ts->addAttribute('x', &pending->pe.pkt, "comment", "{-1 -1 }", false, "comment"); 
  479.   ts->addAttribute('p', &pending->pe.pkt.type, "string", "", false, "packet type"); 
  480.   ts->addAttribute('k', &pending->pe.pkt.wtype, "string", "", false, "packet type"); 
  481.    
  482.   // ---- Session Drop ----
  483.   ts = addTraceSyntax('P', "session drop");
  484.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  485.   ts->addAttribute('s', &pending->pe.src, "int", "-1", true, "source id"); 
  486.   ts->addAttribute('d', &pending->pe.dst, "int", "-1", true, "destination id"); 
  487.   ts->addAttribute('e', &pending->pe.pkt.size, "int", "1", false, "extent"); 
  488.   ts->addAttribute('a', &pending->pe.pkt.attr, "int", "0", false, "attribute"); 
  489.   ts->addAttribute('i', &pending->pe.pkt.id, "int", "0", false, "id"); 
  490.   ts->addAttribute('l', &pending->pe.pkt.energy, "int", "0", false, "energy"); 
  491.   ts->addAttribute('c', &pending->pe.pkt.convid, "string", "", false, "conversation"); 
  492.   ts->addAttribute('x', &pending->pe.pkt, "comment", "{-1 -1 }", false, "comment"); 
  493.   ts->addAttribute('p', &pending->pe.pkt.type, "string", "", false, "packet type"); 
  494.   ts->addAttribute('k', &pending->pe.pkt.wtype, "string", "", false, "packet type"); 
  495.   // ---- Agent Event ----
  496.   ts = addTraceSyntax('a', "agent");
  497.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  498.   ts->addAttribute('s', &pending->ae.src, "int", "-1", true, "source id"); 
  499.   ts->addAttribute('d', &pending->ae.dst, "int", "-1", false, "destination id"); 
  500.   ts->addAttribute('x', &pending->ae.agent.expired, "flag", "0", false, "remove agent"); 
  501. //  ts->addAttribute('X', &pending->ae.agent.expired, "flag", "0", false, "remove agent"); 
  502.   ts->addAttribute('n', &pending->ae.agent.name, "string", "", false, "agent name"); 
  503.    
  504.   // ---- Feature ----
  505.   ts = addTraceSyntax('f', "feature");
  506.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  507.   ts->addAttribute('s', &pending->fe.src, "int", "-1", true, "source id"); 
  508.   ts->addAttribute('d', &pending->fe.dst, "int", "-1", false, "destination id"); 
  509.   ts->addAttribute('x', &pending->fe.feature.expired, "flag", "0", false, "remove feature"); 
  510.   ts->addAttribute('T', &pending->fe.feature.type, "char", "", true, "type"); 
  511.   ts->addAttribute('n', &pending->fe.feature.name, "string", "", true, "name"); 
  512.   ts->addAttribute('a', &pending->fe.feature.agent, "string", "", true, "agent"); 
  513.   ts->addAttribute('v', &pending->fe.feature.value, "string", "", true, "value"); 
  514.   ts->addAttribute('o', &pending->fe.feature.oldvalue, "string", "", false, "previous value"); 
  515.   
  516.   // ---- Group ----
  517.   ts = addTraceSyntax('G', "group");
  518.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  519.   ts->addAttribute('n', &pending->ge.grp.name, "string", "", true, "name"); 
  520.   ts->addAttribute('i', &pending->ge.src, "int", "-1", true, "node id"); 
  521.   ts->addAttribute('a', &pending->ge.grp.mbr, "int", "-1", true, "group id"); 
  522.   ts->addAttribute('x', &pending->ge.grp.flag, "flag", "0", false, "remove from group");
  523.   // ---- LanLink ----
  524.   ts = addTraceSyntax('L', "lan link");
  525.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  526.   ts->addAttribute('s', &pending->lle.src, "int", "-1", true, "source id"); 
  527.   ts->addAttribute('d', &pending->lle.dst, "int", "-1", true, "destination id"); 
  528.   ts->addAttribute('o', &pending->lle.angle, "orientation", "0.0", false, "orientation"); 
  529.   ts->addAttribute('O', &pending->lle.angle, "orientation", "0.0", false, "orientation"); 
  530.   // ---- Mark Node ----
  531.   ts = addTraceSyntax('m', "mark node");
  532.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  533.   ts->addAttribute('n', &pending->me.mark.name, "string", "", true, "name"); 
  534.   ts->addAttribute('s', &pending->me.src, "int", "-1", true, "node id"); 
  535.   ts->addAttribute('c', &pending->me.mark.color, "string", "black", false, "color"); 
  536.   ts->addAttribute('h', &pending->me.mark.shape, "string", "circle", false, "shape (circle, square, hexagon)"); 
  537.   ts->addAttribute('X', &pending->me.mark.expired, "flag", "0", false, "remove mark"); 
  538.   
  539.   // ---- Routing Event ----
  540.   ts = addTraceSyntax('R', "routing event");
  541.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  542.   ts->addAttribute('s', &pending->re.src, "int", "-1", true, "source id"); 
  543.   ts->addAttribute('d', &pending->re.dst, "int", "-1", true, "destination id"); 
  544.   ts->addAttribute('g', &pending->re.route.group, "int", "-1", false, "multicast group"); 
  545.   ts->addAttribute('p', &pending->re.route.pktsrc, "packet source", "-1", false, "packet source id or *"); 
  546.   ts->addAttribute('n', &pending->re.route.neg, "flag", "0", false, "negative cache"); 
  547.   ts->addAttribute('x', &pending->re.route.expired, "flag", "0", false, "this route timed out"); 
  548.   ts->addAttribute('T', &pending->re.route.timeout, "double", "0.0", false, "timeout"); 
  549.   ts->addAttribute('m', &pending->re.route.mode, "string", "iif", false, "mode (iif or oif)"); 
  550.   // ---- Execute TCL Expression ----
  551.   ts = addTraceSyntax('v', "execute tcl expression");
  552.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  553.   ts->addAttribute('e', &pending->ve, "tcl expression", "n", true, "tcl script"); 
  554.   // ---- Trace File Version ----
  555.   ts = addTraceSyntax('V', "set trace file version");
  556.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  557.   ts->addAttribute('v', &pending->version, "string", "", true, "time"); 
  558.   ts->addAttribute('a', &pending->dummy, "int", "0", true, "time"); 
  559.   // ---- Use Nam Graph ----
  560.   ts = addTraceSyntax('N', "use nam graph");
  561.   
  562.   // ---- Wireless Range ----
  563.   ts = addTraceSyntax('W', "wireless range");
  564.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  565.   ts->addAttribute('x', &pending->we.x, "int", "100", true, "X"); 
  566.   ts->addAttribute('y', &pending->we.y, "int", "100", true, "Y"); 
  567.   
  568.   // ---- Energy Status (Future Use) ----
  569.   ts = addTraceSyntax('g', "energy status -- for future use");
  570.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  571.   // ---- Hierarchical Address Space Configuration ----
  572.   // initialized in tcl
  573.   ts = addTraceSyntax('A', "hierarchical address space configuration -- initilization only");
  574.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  575.   ts->addAttribute('n', &pending->hae.hierarchy, "int", "0", false, "hierarchy"); 
  576.   ts->addAttribute('p', &pending->hae.portshift, "int", "0", false, "port shift"); 
  577.   ts->addAttribute('o', &pending->hae.portmask, "hex", "0xffffffff", false, "port mask"); 
  578.   ts->addAttribute('c', &pending->hae.multicast_shift, "int", "0", false, "mulitcast shift"); 
  579.   ts->addAttribute('a', &pending->hae.multicast_mask, "int", "0", false, "multicast mask"); 
  580.   ts->addAttribute('h', &pending->hae.hierarchy, "int", "0", false, "hierarchy"); 
  581.   ts->addAttribute('m', &pending->hae.nodeshift, "int", "0", false, "node shift"); 
  582.   ts->addAttribute('s', &pending->hae.nodemask, "int", "0", false, "node mask"); 
  583.   // ---- Color Table Configuration ----
  584.   // initialized in tcl
  585.   ts = addTraceSyntax('c', "color table configuration -- initialization only");
  586.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  587.   ts->addAttribute('i', &pending->ce.id, "int", "1", true, "id"); 
  588.   ts->addAttribute('n', &pending->ce.color, "string", "black", true, "color"); 
  589.   
  590.   // ---- Define Packet Queue ----
  591.   ts = addTraceSyntax('q', "create packet queue -- initialization only");
  592.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  593.   ts->addAttribute('s', &pending->qe.src, "int", "0", true, "source id"); 
  594.   ts->addAttribute('d', &pending->qe.dst, "int", "0", true, "destination id"); 
  595.   ts->addAttribute('a', &pending->qe.angle, "orientation", "0.0", true, "orientaion"); 
  596.   // ---- layout lan ----
  597.   ts = addTraceSyntax('X', "layout lan");
  598.   ts->addAttribute('t', &pending->time, "time", "0.0", true, "time"); 
  599.   ts->addAttribute('n', &pending->layoutle.name, "string", "", true, "name"); 
  600.   ts->addAttribute('r', &pending->layoutle.rate, "double", "10.0", true, "rate"); 
  601.   ts->addAttribute('D', &pending->layoutle.delay, "double", "0.0", true, "delay"); 
  602.   ts->addAttribute('o', &pending->layoutle.angle, "orientation", "0.0", false, "orientation"); 
  603.   ts->addAttribute('O', &pending->layoutle.angle, "orientation", "0.0", false, "orientation"); 
  604. }
  605. //---------------------------------------------------------------------
  606. //
  607. //---------------------------------------------------------------------
  608. int
  609. ParseTable::print(FILE * stream) {
  610.   TraceSyntax *ts;
  611.   Attribute * attribute;
  612.   int i = 0;
  613.   
  614.   ts = syntax_list;
  615.   while (ts) {
  616.     // Output the type
  617.     i += fprintf(stream, "%c = %sn", ts->type, ts->label);
  618.     attribute = ts->attributes;
  619.     while (attribute) {
  620.       i += fprintf(stream, "     -%c <%s> %sn",attribute->flag, attribute->value_type, attribute->label); 
  621.       attribute = attribute->next;
  622.     }
  623.     ts = ts->next;
  624.   }
  625.   return i;
  626. }
  627. //---------------------------------------------------------------------
  628. //
  629. //---------------------------------------------------------------------
  630. int
  631. ParseTable::printLatex(FILE * stream) {
  632.   TraceSyntax *ts;
  633.   Attribute * attribute;
  634.   int i = 0;
  635.   
  636.   ts = syntax_list;
  637.   while (ts) {
  638.     // Output the type
  639.     i += fprintf(stream, "  \begin{tabular}{llll}n");
  640.     if (ts->type == '#') {
  641.       i += fprintf(stream, "  \%c : & %s & & \\n", ts->type, ts->label);
  642.     } else {
  643.       i += fprintf(stream, "  %c : & %s & & \\n", ts->type, ts->label);
  644.     }
  645.     // Display attribute flags in a latex table
  646.     attribute = ts->attributes;
  647.     if (attribute) {
  648.       // 3 Columns
  649.       while (attribute) {
  650.         if (attribute->flag == '#') {
  651.           i += fprintf(stream, "    &  -\%c ", attribute->flag); 
  652.         } else {
  653.           i += fprintf(stream, "    &  -%c ", attribute->flag); 
  654.         }
  655.         i += fprintf(stream, "& <%s> ", attribute->value_type); 
  656.         i += fprintf(stream, "& %s \\n", attribute->label); 
  657.         attribute = attribute->next;
  658.       }
  659.     }
  660.     i += fprintf(stream, "  \end{tabular}nn");
  661.     ts = ts->next;
  662.   }
  663.   return i;
  664. }
  665. //---------------------------------------------------------------------
  666. //
  667. //---------------------------------------------------------------------
  668. bool
  669. ParseTable::parseLine(char * line) {
  670.   bool success = true;
  671.   char * run = line; // run down the nam event line
  672.   TraceSyntax * ts = syntax_list;
  673.   Attribute * attribute = NULL;
  674.   char attribute_type;
  675.   pending->tt = *line;
  676.   // Skip over comment lines and empty lines
  677.   if (*run == '#' || *run == 'n' || *run == 'r') {
  678.     //<zheng: +++>
  679.     if (strncmp(run,"# nam4wpan #",12) == 0) {
  680.       ParseTable::nam4wpan = true;
  681.     }
  682.     //</zheng: +++>
  683.     return true;
  684.   }
  685.   
  686.   // Find Syntax Type
  687.   while (ts != NULL) {
  688.     if (ts->type == *line) {
  689.       break;
  690.     }
  691.     ts = ts->next;
  692.   }
  693.   if (ts != NULL) {
  694.     // Setup Attribute List to default values
  695.     ts->setDefaultAttributeValues();
  696.     // Skip over Syntax Type id
  697.     run++;
  698.     run = eatSpaces(run);
  699.     
  700.     while (*run != 'n') {
  701.     
  702.       //Check for Attribute Flag 
  703.       if (*run != '-' && ts->type != 'v') {
  704.         // Special Case for tcl expression flag
  705.         //   The old design has the syntax "v -t <time> <expression>"
  706.         while (*run != '-' && *run != 'n' && *run != EOF) {
  707.           run++;
  708.         }
  709.       }
  710.       if (*run == 'n' || *run == EOF) {
  711.         // Something is seriously wrong with this line in the script
  712.         // so bail out with an error
  713.         fprintf(stderr, "Unexpected end of line in: %s", line);
  714.         fprintf(stderr, "Perhaps you are missing a value following the attribute flag.n");
  715.         if (attribute) {
  716.           fprintf(stderr, "Last parsed attribute flag was -%cnn", attribute->flag);
  717.         }
  718.         break;
  719.       } else if (*run != '-' && ts->type == 'v') {
  720.         // Missing -e flag
  721.         // Report the new syntax but setup the attribute
  722.         // as if we are using it
  723.         
  724.         fprintf(stderr, "Nam syntax has changed: %s", line);
  725.         fprintf(stderr, "Please use this format in the future.n");
  726.         fprintf(stderr, "v -t <time> -e <tcl expression>nn");
  727.         attribute_type = 'e';
  728.       } else {
  729.         // Eat the dash and set the current attribute
  730.         run++;
  731.         attribute_type = *run;
  732.         run++;
  733.       }
  734.       //Match in Table
  735.       attribute = ts->attributes;
  736.       while (attribute != NULL) {
  737.         if (attribute_type == attribute->flag) {
  738.           break;
  739.         }
  740.         attribute = attribute->next;
  741.       }
  742.       //Read in Value
  743.       if (attribute) {
  744.         // Eat the flag and whitespace, to end on the value
  745.         run = eatSpaces(run);
  746.         run = attribute->parseValue(run, line);
  747.         attribute->seen = true;
  748.       } else {
  749.         fprintf(stderr, "Unknown Flag -%c in: %sn", attribute_type, line);
  750.         // Skip to next attribute
  751.         while (*run != '-' && *run != 'n') {
  752.           run++;
  753.         }
  754.       }
  755.       run = eatSpaces(run);
  756.     }
  757.     // Check for required attributes
  758.     attribute = ts->attributes;
  759.     while (attribute != NULL) {
  760.       if (attribute->required && !attribute->seen) {
  761.         success = false;
  762.         fprintf(stderr, "Missing required flag -%c in: %sn", attribute->flag, line);
  763.       }
  764.       attribute = attribute->next;  
  765.     }
  766.   } else {
  767.     fprintf(stderr, "Unknown nam event id type: %sn", line);
  768.     success = false;
  769.   }
  770.   return success;
  771. }
  772. //---------------------------------------------------------------------
  773. //
  774. //---------------------------------------------------------------------
  775. TraceSyntax * 
  776. ParseTable::addTraceSyntax(char id, char * label) {
  777.   TraceSyntax * ts;
  778.   
  779.   if (!syntax_list) {
  780.     // Create list and add this as the first member
  781.     ts = new TraceSyntax(id, label);
  782.     syntax_list =  ts;
  783.     syntax_list_tail = ts;
  784.   } else {
  785.     // Check for duplicates
  786.     ts = syntax_list;
  787.     while (ts) {
  788.       if (ts->type == id) {
  789.         break;
  790.       }
  791.       ts = ts->next;
  792.     }
  793.     if (!ts) {
  794.       // Add it to the end of the list
  795.       ts = new TraceSyntax(id, label);
  796.       syntax_list_tail->next = ts;
  797.       syntax_list_tail = ts;
  798.     }
  799.   }
  800.   
  801.   return ts;
  802. }
  803. //---------------------------------------------------------------------
  804. //
  805. //---------------------------------------------------------------------
  806. char *
  807. eatSpaces(char * marker) {
  808.   while (*marker == ' ' || *marker == 't') {
  809.     marker++; 
  810.   }
  811.   return marker;
  812. }
  813. //---------------------------------------------------------------------
  814. //
  815. //---------------------------------------------------------------------
  816. char *
  817. advanceToSpace(char * marker) {
  818.   while (!isspace(*marker)) {
  819.     marker++; 
  820.   }
  821.   return marker;
  822. }
  823. //---------------------------------------------------------------------
  824. //
  825. //---------------------------------------------------------------------
  826. char * advanceToNextFlag(char * marker) {
  827.   while (*marker != '-' && *marker != 'n' && *marker != '') {
  828.     marker++;
  829.   }
  830.   return marker;
  831. }
  832. //---------------------------------------------------------------------
  833. //
  834. //---------------------------------------------------------------------
  835. char * advanceToEndofLine(char * marker) {
  836.   while (*marker != 'n' && *marker != '') {
  837.     marker++;
  838.   }
  839.   return marker;
  840. }
  841. //---------------------------------------------------------------------
  842. // char *
  843. // ParseTable::parse_string(char *orig, char * output)
  844. //   - Extracts the string after a flag in a nam animation line.
  845. //   - Removes any double quotes, null terminates the string 
  846. //     and copies it into the output variable.
  847. //   - Returns the location after the extracted string in the original
  848. //     nam animation line.
  849. //   - Requires that the original pointer points to the start of 
  850. //     the string.
  851. //
  852. //   - Strings can be double quoted or have no quotes
  853. //
  854. //     Note: May need to add in r check for Micro$oft Windows
  855. //---------------------------------------------------------------------
  856. char *
  857. extractString(char * original, char * output) {
  858.   char * run; // run along the string
  859.   int count = 0;  // size of the copied string, should be less than MAXNAME
  860.   run = original;
  861.   // Skip over first double quote, if any
  862.   if (*run == '"') {
  863.     run++;
  864.     // Copy over to output
  865.     while (count < MAXNAME &&
  866.            *run != '"' &&
  867.            *run != 'n' &&
  868.            *run != 'r') {
  869.       output[count] = *run;
  870.       run++;
  871.       count++;
  872.     }
  873.   
  874.     // Skip over last double quote, if any
  875.     if (*run == '"') {
  876.       run++;
  877.     }
  878.   } else {
  879.     // Copy over to output
  880.     while (count < MAXNAME &&
  881.            *run != '"' &&
  882.            *run != ' ' &&
  883.            *run != 'n' &&
  884.            *run != 'r') {
  885.       output[count] = *run;
  886.       run++;
  887.       count++;
  888.     }
  889.   }
  890.   // Null Terminate the String
  891.   if (count < MAXNAME) {
  892.     output[count] = '';
  893.     count++;
  894.   } else {
  895.     count--;
  896.     output[count] = '';
  897.   }
  898.       
  899.   return run;
  900. }