/* CS 555 * Programming Assignment #2 * * Helper code to parse event files. * */ #include #include /* Maximum expected input/output line length. */ #define MAXLINE 10000 /* There are seven distinct events in our simulation */ typedef enum { EVENT_INIT, EVENT_LSP, EVENT_UFWD, EVENT_MFWD, EVENT_ADV, EVENT_JOIN, EVENT_QUIT } e_type; /* An LSP pair consists of a host and a distance */ typedef struct { int host; int distance; } lsp_pair; /* An event consists of many fields (not all used by all events) * - an integer timestamp * - a type * - a host ID * - a sequence number * - an array of lsp_pairs * - a multicast address * - a time-to-live field */ typedef struct { int timestamp; e_type type; int unihost; int seqno; lsp_pair *pairs; int num_pairs; int multiaddr; int TTL; } EVENT; /* Parse the next event from the input file and return it. */ /* Return zero on success and -1 on failure or when end-of-file is reached. */ /* N.B.: There may be garbage in unused fields of a particular event */ int parse_event (FILE *infp, EVENT *the_main_event) { char line[MAXLINE]; char first_char = '\0'; int offset, i; /* helpers for parsing */ int more_offset; int left_brace_count; while (fgets (line, MAXLINE, infp) != NULL) { /* Skip blank lines and comments */ if ((sscanf (line, " %c", &first_char) == 0) || (first_char == '#') || (first_char == '\0')) { continue; } /* Parse a real input line */ else if (sscanf (line, " %d F %d %d", &the_main_event->timestamp, &the_main_event->unihost, &the_main_event->multiaddr) == 3) { /* Multicast forwarding event */ the_main_event->type = EVENT_MFWD; return 0; } else if (sscanf (line, " %d F %d ", &the_main_event->timestamp, &the_main_event->unihost) == 2) { /* Unicast forwarding event */ the_main_event->type = EVENT_UFWD; return 0; } else if (sscanf (line, " %d J %d %d", &the_main_event->timestamp, &the_main_event->unihost, &the_main_event->multiaddr) == 3) { /* Multicast join event */ the_main_event->type = EVENT_JOIN; return 0; } else if (sscanf (line, " %d Q %d %d", &the_main_event->timestamp, &the_main_event->unihost, &the_main_event->multiaddr) == 3) { /* Multicast quit event */ the_main_event->type = EVENT_QUIT; return 0; } else if (sscanf (line, " %d A %d %d %d", &the_main_event->timestamp, &the_main_event->unihost, &the_main_event->multiaddr, &the_main_event->TTL) == 4) { /* Multicast advertisement */ the_main_event->type = EVENT_ADV; return 0; } else { /* Initialization, link-state packet, or garbage */ if (sscanf (line, "%d I %d%n", &the_main_event->timestamp, &the_main_event->unihost, &offset) == 2) { /* Initialization*/ the_main_event->type = EVENT_INIT; } else if (sscanf (line, "%d L %d %d%n", &the_main_event->timestamp, &the_main_event->unihost, &the_main_event->seqno, &offset) == 3) { /* Initialization*/ the_main_event->type = EVENT_LSP; } else return -1; /* Now, munge through the lsp-pairs */ /* This is somewhat painful, so don't look */ /* Count the left braces, so we know how much space to allocate */ the_main_event->num_pairs = 0; for (i = offset; line[i] != '\0'; i++) { if (line[i] == '<') { the_main_event->num_pairs++; } } the_main_event->pairs = (lsp_pair *) calloc (sizeof(lsp_pair), the_main_event->num_pairs); i = 0; while (sscanf (&line[offset], " <%d, %d >%n", &(the_main_event->pairs[i].host), &(the_main_event->pairs[i].distance), &more_offset) == 2) { i++; offset += more_offset; } return 0; } } return -1; } /* This is just to test the parsing of events. Once you are * convinced that the parser works correctly, this can be * ignored. */ void dump_event(EVENT evt) { int i; switch (evt.type) { case EVENT_JOIN: printf ("JOIN, id = %d, addr = %d\n", evt.unihost, evt.multiaddr); break; case EVENT_QUIT: printf ("QUIT, id = %d, addr = %d\n", evt.unihost, evt.multiaddr); break; case EVENT_ADV: printf ("ADV, id = %d, addr = %d, TTL = %d\n", evt.unihost, evt.multiaddr, evt.TTL); break; case EVENT_UFWD: printf ("UFWD, host = %d\n", evt.unihost); break; case EVENT_MFWD: printf ("MFWD, source = %d, addr = %d\n", evt.unihost, evt.multiaddr); break; case EVENT_INIT: case EVENT_LSP: if (evt.type == EVENT_INIT) { printf ("INIT, id = %d, ", evt.unihost); } else { printf ("LSP, source = %d, seqno = %d, ", evt.unihost, evt.seqno); } printf ("PAIRS = "); for (i = 0; i < evt.num_pairs; i ++) { printf ("<%d, %d> ", evt.pairs[i].host, evt.pairs[i].distance); } printf ("\n"); break; default: printf ("ERROR: Invalid event parsed. \n"); } } /* Parse events and dump them to stdout */ int main (void) { EVENT evt; while (parse_event (stdin, &evt) != -1) { dump_event(evt); } return; }