MP_GLOBAL int __mp_getopt(unsigned long n, char **a, char *s, option *l) { static char *t; option *m; char *b, *p; int r; __mp_optarg = NULL; /* If the index of the current option is zero or if there are no more * options in this argument then we proceed to the next argument. */ if ((__mp_optindex == 0) || ((t != NULL) && (*t == '\0'))) { __mp_optindex++; t = NULL; } /* Get the basename of the filename that the program was invoked with so * that we can use that for any diagnostics. */ b = __mp_basename(a[0]); /* If there is not a current option then attempt to locate it, otherwise * return EOF if there are no more options. */ if (t == NULL) { if (__mp_optindex >= n) return EOF; t = a[__mp_optindex]; /* Stop parsing options if either the argument is not an option, if it * is a single dash (representing stdin) or if it is a double dash * representing the end of options. */ if ((*t != '-') || (t[1] == '\0') || ((t[1] == '-') && (t[2] == '\0'))) { if ((*t == '-') && (t[1] == '-') && (t[2] == '\0')) __mp_optindex++; t = NULL; return EOF; } t++; /* Parse a long option and possibly its argument. */ if ((*t == '-') && (l != NULL)) { t++; /* Check that the option appears in the long options table. */ if ((m = findopt(t, l, &t)) == NULL) { fprintf(stderr, "%s: Illegal option `--%s'\n", b, t); __mp_optindex++; t = NULL; return '?'; } /* Check to see if the option takes an argument. */ if (m->arg) if (*t == '\0') { /* The rest of this argument is empty, so we proceed to the * next argument. */ if ((++__mp_optindex >= n) || (strcmp(a[__mp_optindex], "--") == 0)) { fprintf(stderr, "%s: Option `--%s' requires an " "argument\n", b, m->name); t = NULL; return '?'; } __mp_optarg = a[__mp_optindex]; } else __mp_optarg = t; else if (*t != '\0') fprintf(stderr, "%s: Ignoring argument `%s' for option " "`--%s'\n", b, t, m->name); __mp_optindex++; t = NULL; return m->value; } } /* Check that the option appears in the string of recognised options. */ if ((*t == ':') || ((p = strchr(s, *t)) == NULL)) { fprintf(stderr, "%s: Illegal option `-%c'\n", b, *t++); return '?'; } r = *t++; /* Check to see if the option takes an argument. */ if (p[1] == ':') { if (*t == '\0') { /* The rest of this argument is empty, so we proceed to the next * argument. */ if ((++__mp_optindex >= n) || (strcmp(a[__mp_optindex], "--") == 0)) { fprintf(stderr, "%s: Option `-%c' requires an argument\n", b, r); t = NULL; return '?'; } __mp_optarg = a[__mp_optindex]; } else __mp_optarg = t; __mp_optindex++; t = NULL; } return r; }
int main(int argc, char **argv) { char b[256]; char *f, *g; int c, e, h, r, v; g = NULL; e = h = v = 0; r = EXIT_SUCCESS; maxstack = 1; progname = __mp_basename(argv[0]); while ((c = __mp_getopt(argc, argv, __mp_shortopts(b, options_table), options_table)) != EOF) switch (c) { case OF_ADDRESSES: useaddresses = 1; break; case OF_CALLGRAPH: showgraph = 1; break; case OF_COUNTS: showcounts = 1; break; case OF_GRAPHFILE: g = __mp_optarg; break; case OF_HELP: h = 1; break; case OF_LEAKS: showleaks = 1; break; case OF_STACKDEPTH: if (!__mp_getnum(progname, __mp_optarg, (long *) &maxstack, 1)) e = 1; break; case OF_VERSION: v = 1; break; default: e = 1; break; } argc -= __mp_optindex; argv += __mp_optindex; if (v == 1) { fprintf(stdout, "%s %s\n%s %s\n\n", progname, PROGVERSION, __mp_copyright, __mp_author); fputs("This is free software, and you are welcome to redistribute it " "under certain\n", stdout); fputs("conditions; see the GNU Lesser General Public License for " "details.\n\n", stdout); fputs("For the latest mpatrol release and documentation,\n", stdout); fprintf(stdout, "visit %s.\n\n", __mp_homepage); } if (argc > 1) e = 1; if ((e == 1) || (h == 1)) { fprintf(stdout, "Usage: %s [options] [file]\n\n", progname); if (h == 0) fprintf(stdout, "Type `%s --help' for a complete list of " "options.\n", progname); else __mp_showopts(options_table); if (e == 1) exit(EXIT_FAILURE); exit(EXIT_SUCCESS); } if (argc == 1) f = argv[0]; else f = MP_PROFFILE; acount = dcount = 0; atotal = dtotal = 0; acounts = dcounts = NULL; atotals = dtotals = 0; binsize = 0; data = NULL; datasize = 0; nodes = NULL; nodesize = 0; addrs = NULL; symbols = NULL; sbound = mbound = lbound = 0; __mp_newtree(&proftree); __mp_newtree(&temptree); __mp_newlist(&edgelist); __mp_newgraph(&graph); if (strcmp(f, "-") == 0) proffile = stdin; else if ((proffile = fopen(f, "rb")) == NULL) { fprintf(stderr, "%s: Cannot open file `%s'\n", progname, f); exit(EXIT_FAILURE); } readfile(); fclose(proffile); bintable(); fputs("\n\n", stdout); directtable(); fputs("\n\n", stdout); leaktable(); /* The reason that the allocation call graph is not used for the direct * allocation and memory leak tables is that the code to build and display * the allocation call graph was added much later. Rather than convert * these tables to use the new call graph, I decided to keep the code that * already worked and only use the call graph for any new tables. */ buildgraph(); if (showgraph) { fputs("\n\n", stdout); callgraph(); } if (g != NULL) { if (strcmp(g, "stdout") == 0) graphfile = stdout; else if (strcmp(g, "stderr") == 0) graphfile = stderr; else if ((graphfile = fopen(g, "w")) == NULL) { fprintf(stderr, "%s: Cannot open file `%s'\n", progname, g); r = EXIT_FAILURE; } if (r == EXIT_SUCCESS) { fprintf(graphfile, "/* produced by %s %s from %s */\n\n", progname, PROGVERSION, f); if (showleaks) fputs("digraph \"memory leak call graph\"\n{\n", graphfile); else fputs("digraph \"allocation call graph\"\n{\n", graphfile); writegraph(NULL, &graph.start); fputs("}\n", graphfile); if ((graphfile != stdout) && (graphfile != stderr)) fclose(graphfile); } } deletegraph(); if (acounts != NULL) free(acounts); if (dcounts != NULL) free(dcounts); if (data != NULL) free(data); if (nodes != NULL) free(nodes); if (addrs != NULL) free(addrs); if (symbols != NULL) free(symbols); return r; }
int main(int argc, char **argv) { struct { char x; void *y; } z; char b[256]; char *f, *s, *t; #if MP_GUI_SUPPORT XGCValues g; #endif /* MP_GUI_SUPPORT */ long n; int c, e, h, v; #if MP_GUI_SUPPORT appwidget = XtVaAppInitialize(&appcontext, "MPTrace", options, XtNumber(options), &argc, argv, NULL, NULL); XtVaGetApplicationResources(appwidget, NULL, resources, XtNumber(resources), NULL); #endif /* MP_GUI_SUPPORT */ s = t = NULL; e = h = v = 0; progname = __mp_basename(argv[0]); while ((c = __mp_getopt(argc, argv, __mp_shortopts(b, options_table), options_table)) != EOF) switch (c) { case OF_GUI: #if MP_GUI_SUPPORT usegui = 1; #endif /* MP_GUI_SUPPORT */ break; case OF_HATFFILE: t = __mp_optarg; break; case OF_HELP: h = 1; break; case OF_SIMFILE: s = __mp_optarg; break; case OF_SOURCE: displaysource = 1; break; case OF_VERBOSE: verbose = 1; break; case OF_VERSION: v = 1; break; default: e = 1; break; } argc -= __mp_optindex; argv += __mp_optindex; if (v == 1) { fprintf(stdout, "%s %s\n%s %s\n\n", progname, PROGVERSION, __mp_copyright, __mp_author); fputs("This is free software, and you are welcome to redistribute it " "under certain\n", stdout); fputs("conditions; see the GNU Lesser General Public License for " "details.\n\n", stdout); fputs("For the latest mpatrol release and documentation,\n", stdout); fprintf(stdout, "visit %s.\n\n", __mp_homepage); } if (argc > 1) e = 1; if ((e == 1) || (h == 1)) { fprintf(stdout, "Usage: %s [options] [file]\n\n", progname); if (h == 0) fprintf(stdout, "Type `%s --help' for a complete list of " "options.\n", progname); else __mp_showopts(options_table); if (e == 1) exit(EXIT_FAILURE); exit(EXIT_SUCCESS); } if (argc == 1) f = argv[0]; else f = MP_TRACEFILE; __mp_newtree(&alloctree); if (strcmp(f, "-") == 0) tracefile = stdin; else if ((tracefile = fopen(f, "rb")) == NULL) { fprintf(stderr, "%s: Cannot open file `%s'\n", progname, f); exit(EXIT_FAILURE); } currentevent = 0; bufferpos = buffer; bufferlen = 0; n = (char *) &z.y - &z.x; __mp_newslots(&table, sizeof(void *), __mp_poweroftwo(n)); __mp_initslots(&table, tableslots, sizeof(tableslots)); maxslots = 1; if (s != NULL) { if (strcmp(s, "stdout") == 0) simfile = stdout; else if (strcmp(s, "stderr") == 0) simfile = stderr; else if ((simfile = fopen(s, "w")) == NULL) { fprintf(stderr, "%s: Cannot open file `%s'\n", progname, s); exit(EXIT_FAILURE); } fprintf(simfile, "/* produced by %s %s from %s */\n\n\n", progname, PROGVERSION, f); fputs("#include <stdio.h>\n", simfile); fputs("#include <stdlib.h>\n\n\n", simfile); fputs("typedef struct event\n{\n", simfile); fputs(" unsigned long index;\n", simfile); fputs(" unsigned long size;\n", simfile); fputs(" char resize;\n", simfile); fputs("}\nevent;\n\n\n", simfile); fputs("static event events[] =\n{\n", simfile); } if (t != NULL) { if (strcmp(t, "stdout") == 0) hatffile = stdout; else if (strcmp(t, "stderr") == 0) hatffile = stderr; else if ((hatffile = fopen(t, "w")) == NULL) { fprintf(stderr, "%s: Cannot open file `%s'\n", progname, t); exit(EXIT_FAILURE); } fprintf(hatffile, "## Tracename: %s\n", t); fputs("## Author: Unknown\n", hatffile); fputs("## Date: Unknown\n", hatffile); fputs("## DTDURL: hatf.dtd\n", hatffile); fprintf(hatffile, "## Description: Converted to HATF by %s %s.\n\n", progname, PROGVERSION); } readfile(); #if MP_GUI_SUPPORT if (usegui) { appdisplay = XtDisplay(appwidget); appscreen = XtScreen(appwidget); addrscale = (((addrspace * 1048576) - 1) / (width * height)) + 1; /* Set up the main application window and scrollable drawing area. * Also set up a pixmap to backup the drawing area. */ mainwidget = XtVaCreateManagedWidget("main", xmScrolledWindowWidgetClass, appwidget, XmNwidth, vwidth, XmNheight, vheight, XmNscrollingPolicy, XmAUTOMATIC, XmNscrollBarDisplayPolicy, XmAS_NEEDED, NULL); drawwidget = XtVaCreateManagedWidget("draw", xmDrawingAreaWidgetClass, mainwidget, XmNwidth, width, XmNheight, height, NULL); pixmap = XCreatePixmap(appdisplay, RootWindowOfScreen(appscreen), width, height, DefaultDepthOfScreen(appscreen)); /* Set up the graphics contexts that are used for drawing in different * colours. */ g.foreground = uncol; ungc = XCreateGC(appdisplay, RootWindowOfScreen(appscreen), GCForeground, &g); g.foreground = incol; ingc = XCreateGC(appdisplay, RootWindowOfScreen(appscreen), GCForeground, &g); g.foreground = frcol; frgc = XCreateGC(appdisplay, RootWindowOfScreen(appscreen), GCForeground, &g); g.foreground = alcol; algc = XCreateGC(appdisplay, RootWindowOfScreen(appscreen), GCForeground, &g); /* Add a callback procedure to handle the refreshing of the drawing * area and also a work procedure to read events from the tracing * output file. Then initialise the drawing area and enter the main X * application loop. */ XtAddCallback(drawwidget, XmNexposeCallback, (XtCallbackProc) redrawmemory, NULL); XtAppAddWorkProc(appcontext, (XtWorkProc) readevent, NULL); XtRealizeWidget(appwidget); XFillRectangle(appdisplay, XtWindow(drawwidget), ungc, 0, 0, width - 1, height - 1); XFillRectangle(appdisplay, pixmap, ungc, 0, 0, width - 1, height - 1); XtAppMainLoop(appcontext); } #endif /* MP_GUI_SUPPORT */ return EXIT_SUCCESS; }