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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1991,1993 Regents of the University of 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 Computer Systems
  16.  * Engineering Group at Lawrence Berkeley Laboratory.
  17.  * 4. Neither the name of the University nor of the Laboratory 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.  * @(#) $Header: /cvsroot/nsnam/nam-1/main.cc,v 1.57 2003/10/11 22:56:50 xuanc Exp $ (LBL)
  34.  */
  35. #include <stdlib.h>
  36. #ifndef WIN32
  37. #include <unistd.h>
  38. #else
  39. #include <windows.h>
  40. #endif
  41. #include "netview.h"
  42. #include "tclcl.h"
  43. #include "trace.h"
  44. #include "paint.h"
  45. #include "state.h"
  46. #include "parser.h"
  47.  
  48. //#include "../tcl-debug-2.0/tcldbg.h"
  49.  
  50. extern "C" {
  51. #include <tk.h>
  52. }
  53. static void
  54. usage()
  55. {
  56. fprintf(stderr, "
  57. Usage: nam [-a -S -s -f init_script -d display -j jump -r rate -k initPort] 
  58. tracefilesn
  59. n
  60. -a: create a new nam instancen
  61. -S: synchronize Xn
  62. -s: synchronize multiple tracesn
  63. -j: startup timen
  64. -r: initial animation raten
  65. -f: initialization OTcl scriptn
  66. -k: initial socket port numbern");
  67.         exit(1);
  68. }
  69. #ifdef WIN32
  70. extern "C" int getopt(int, char**, char*);
  71. #endif
  72. extern "C" char *optarg;
  73. extern "C" int optind;
  74. const char* disparg(int argc, const char*const* argv, const char* optstr)
  75. {
  76. const char* display = 0;
  77. int op;
  78. while ((op = getopt(argc, (char**)argv, (char*)optstr)) != -1) {
  79. if (op == 'd') {
  80. display = optarg;
  81. break;
  82. }
  83. }
  84. optind = 1;
  85. return (display);
  86. }
  87. const char* namearg(int argc, const char*const* argv, const char* optstr)
  88. {
  89. const char* appname = 0;
  90. int op;
  91. while ((op = getopt(argc, (char**)argv, (char*)optstr)) != -1) {
  92. if (op == 'N') {
  93. appname = optarg;
  94. break;
  95. }
  96. }
  97. optind = 1;
  98. return (appname);
  99. }
  100. #include "bitmap/play.xbm"
  101. #include "bitmap/back.xbm"
  102. #include "bitmap/stop.xbm"
  103. #include "bitmap/eject.xbm"
  104. #include "bitmap/rew.xbm"
  105. #include "bitmap/ff.xbm"
  106. #include "bitmap/monitors.xbm"
  107. #include "bitmap/time.xbm"
  108. #include "bitmap/zoomin.xbm"
  109. #include "bitmap/zoomout.xbm"
  110. #include "bitmap/pullright.xbm"
  111. #include "bitmap/mark1.xbm"
  112. #include "bitmap/mark2.xbm"
  113. #include "bitmap/mark3.xbm"
  114. #include "bitmap/mark4.xbm"
  115. #include "bitmap/mark5.xbm"
  116. #include "bitmap/mark6.xbm"
  117. #include "bitmap/mark7.xbm"
  118. #include "bitmap/mark8.xbm"
  119. #include "bitmap/updir.xbm"
  120. //#include "bitmap/edit.xbm"
  121. #include "bitmap/nodeup.xbm" 
  122. #include "bitmap/nodedown.xbm" 
  123. #include "bitmap/select.xbm"
  124. #include "bitmap/addnode.xbm"
  125. #include "bitmap/addlink.xbm"
  126. #include "bitmap/cut.xbm"
  127. #include "bitmap/delete.xbm"
  128. #include "bitmap/netedit.xbm"
  129. #include "bitmap/netview.xbm"
  130. void loadbitmaps(Tcl_Interp* tcl)
  131. {
  132. //   Tk_DefineBitmap(tcl, Tk_GetUid("edit"),
  133. //   edit_bits, edit_width, edit_height);
  134. Tk_DefineBitmap(tcl, Tk_GetUid("netedit"),
  135. netedit_bits, netedit_width, netedit_height);
  136. Tk_DefineBitmap(tcl, Tk_GetUid("netview"),
  137. netview_bits, netview_width, netview_height);
  138. Tk_DefineBitmap(tcl, Tk_GetUid("nodeup"),
  139. nodeup_bits, nodeup_width, nodeup_height);
  140. Tk_DefineBitmap(tcl, Tk_GetUid("nodedown"),
  141. nodedown_bits, nodedown_width, nodedown_height);
  142. Tk_DefineBitmap(tcl, Tk_GetUid("play"),
  143. play_bits, play_width, play_height);
  144. Tk_DefineBitmap(tcl, Tk_GetUid("back"),
  145. back_bits, back_width, back_height);
  146. Tk_DefineBitmap(tcl, Tk_GetUid("stop"),
  147. stop_bits, stop_width, stop_height);
  148. Tk_DefineBitmap(tcl, Tk_GetUid("eject"),
  149. eject_bits, eject_width, eject_height);
  150. Tk_DefineBitmap(tcl, Tk_GetUid("rew"),
  151. rew_bits, rew_width, rew_height);
  152. Tk_DefineBitmap(tcl, Tk_GetUid("ff"),
  153. ff_bits, ff_width, ff_height);
  154. Tk_DefineBitmap(tcl, Tk_GetUid("monitors"),
  155. monitors_bits, monitors_width, monitors_height);
  156. Tk_DefineBitmap(tcl, Tk_GetUid("time"),
  157. time_bits, time_width, time_height);
  158. Tk_DefineBitmap(tcl, Tk_GetUid("zoomin"),
  159. zoomin_bits, zoomin_width, zoomin_height);
  160. Tk_DefineBitmap(tcl, Tk_GetUid("zoomout"),
  161. zoomout_bits, zoomout_width, zoomout_height);
  162. Tk_DefineBitmap(tcl, Tk_GetUid("pullright"),
  163. pullright_bits, pullright_width, pullright_height);
  164.   // Used in nam editor toolbar
  165.   Tk_DefineBitmap(tcl, Tk_GetUid("select"),
  166.                   select_bits, select_width, select_height);
  167.   Tk_DefineBitmap(tcl, Tk_GetUid("addnode"),
  168.                   addnode_bits, addnode_width, addnode_height);
  169.   Tk_DefineBitmap(tcl, Tk_GetUid("addlink"),
  170.                   addlink_bits, addlink_width, addlink_height);
  171.   Tk_DefineBitmap(tcl, Tk_GetUid("cut"),
  172.                   cut_bits, cut_width, cut_height);
  173.   Tk_DefineBitmap(tcl, Tk_GetUid("delete"),
  174.                   delete_bits, delete_width, delete_height);
  175.   Tk_DefineBitmap(tcl, Tk_GetUid("mark1"),
  176.                   mark1_bits, mark1_width, mark1_height);
  177.   Tk_DefineBitmap(tcl, Tk_GetUid("mark2"),
  178.                   mark2_bits, mark2_width, mark2_height);
  179.   Tk_DefineBitmap(tcl, Tk_GetUid("mark3"),
  180.                   mark3_bits, mark3_width, mark3_height);
  181.   Tk_DefineBitmap(tcl, Tk_GetUid("mark4"),
  182.                   mark4_bits, mark4_width, mark4_height);
  183.   Tk_DefineBitmap(tcl, Tk_GetUid("mark5"),
  184.                   mark5_bits, mark5_width, mark5_height);
  185.   Tk_DefineBitmap(tcl, Tk_GetUid("mark6"),
  186.                   mark6_bits, mark6_width, mark6_height);
  187.   Tk_DefineBitmap(tcl, Tk_GetUid("mark7"),
  188.                   mark7_bits, mark7_width, mark7_height);
  189.   Tk_DefineBitmap(tcl, Tk_GetUid("mark8"),
  190.                   mark8_bits, mark8_width, mark8_height);
  191.   Tk_DefineBitmap(tcl, Tk_GetUid("updir"),
  192.                   updir_bits, updir_width, updir_height);
  193. }
  194. void adios()
  195. {
  196. exit(0);
  197. }
  198. static int cmd_adios(ClientData , Tcl_Interp* , int , CONST84 char **)
  199. {
  200. adios();
  201. /*NOTREACHED*/
  202. return (0);
  203. }
  204. extern "C" char version[];
  205. static int cmd_version(ClientData , Tcl_Interp* tcl, int , CONST84 char **)
  206. {
  207. tcl->result = version;
  208. return (TCL_OK);
  209. }
  210. char* parse_assignment(char* cp)
  211. {
  212. cp = strchr(cp, '=');
  213. if (cp != 0) {
  214. *cp = 0;
  215. return (cp + 1);
  216. } else
  217. return ("true");
  218. }
  219. static void process_geometry(Tk_Window tk, char* geomArg)
  220. {
  221. /*
  222.  * Valid formats:
  223.  *   <width>x<height>[+-]<x>[+-]<y> or
  224.  *   <width>x<height> or
  225.  *   [+-]x[+-]y
  226.  */
  227. Tcl &tcl = Tcl::instance();
  228. // xxx: geomArg could have bogus stuff in it (security hole)
  229. // but nam doesn't run trusted, so no problem.
  230. tcl.evalf("wm geometry %s %s", Tk_PathName(tk), geomArg);
  231. // tclcl will report the error, if any.
  232. }
  233. // What is it used for???
  234. // extern "C" void Blt_Init(Tcl_Interp*);
  235. #ifdef WIN32
  236. EXTERN int platformInit(Tcl_Interp* interp);
  237. #endif
  238. /* TkPlatformInit was moved to tkUnixInit.c */
  239. #if defined(WIN32) && defined(STATIC_LIB)
  240. #include <tkWin.h>
  241. #include <stdlib.h>
  242. extern "C" {
  243. extern BOOL APIENTRY Tk_LibMain(HINSTANCE hInstance, DWORD reason, 
  244. LPVOID reserved);
  245. extern BOOL APIENTRY Tcl_LibMain(HINSTANCE hInstance, DWORD reason, 
  246.  LPVOID reserved);
  247. /* procedure to call before exiting to clean up */
  248. void static_exit(void) {
  249. HINSTANCE hInstance = Tk_GetHINSTANCE();
  250. Tcl_LibMain(hInstance, DLL_PROCESS_DETACH, NULL);
  251. Tk_LibMain(hInstance, DLL_PROCESS_DETACH, NULL);
  252. }
  253. }
  254. #endif /* defined(WIN32) && defined(STATIC_LIB) */
  255. #ifdef HAVE_LIBTCLDBG
  256. extern "C" {
  257. extern int Tcldbg_Init(Tcl_Interp *);   // hackorama
  258. }
  259. #endif
  260. void
  261. die(char *s)
  262. {
  263. fprintf(stderr, "%s", s);
  264. exit (1);
  265. }
  266. /*ARGSUSED*/
  267. int 
  268. main(int argc, char **argv) {
  269. const char* script = 0; // configurations to be loaded
  270. const char* optstr = "d:M:j:pG:r:u:X:t:i:P:g:N:c:S:f:asmk:zk:xp";
  271. TraceEvent te;  // Used to display parsetable
  272. ParseTable pt(&te);  // Used to display parsetable
  273. /*
  274.  * We have to initialize libtcl and libtk if we are under Win32
  275.  * and we are using static version of libtcl8.0p2 and libtk8.0p2.
  276.  * Because in those distributions, Sun only supports DLL, but 
  277.  * not static lib. They require initializations in DllMain().
  278.  * The Berkeley folks (tecklee) built static versions by 
  279.  * forcing calls to DllMain() inside WinMain(). Because nam 
  280.  * is built as a console app in win32, we have to do those 
  281.  * initializations here, in main().
  282.  */
  283. #if defined(WIN32) && defined(STATIC_LIB)
  284. HINSTANCE hInstance = GetModuleHandle(NULL);
  285. Tcl_LibMain(hInstance, DLL_PROCESS_ATTACH, NULL);
  286. Tk_LibMain(hInstance, DLL_PROCESS_ATTACH, NULL);
  287. atexit(static_exit);
  288. #endif
  289. /*
  290.  * Process display option here before the rest of the options
  291.  * because it's needed when creating the main application window.
  292.  */
  293. const char* display = disparg(argc, argv, optstr);
  294. // hold pointer to application name for send
  295. const char* appname = namearg(argc, argv, optstr);
  296. if (!appname) 
  297. appname = "nam";
  298. #ifdef notdef
  299. fprintf(stderr, "Application name is %sn", appname);
  300. #endif
  301. Tcl_Interp *interp = Tcl_CreateInterp();
  302. #if 0
  303. if (Tcl_Init(interp) == TCL_ERROR) {
  304. printf("%sn", interp->result);
  305. abort();
  306. }
  307. #endif
  308. #if TCL_MAJOR_VERSION < 8
  309.         Tcl_SetVar(interp, "tcl_library", "./lib/tcl7.6", TCL_GLOBAL_ONLY);
  310.         Tcl_SetVar(interp, "tk_library", "./lib/tk4.2", TCL_GLOBAL_ONLY);
  311. #else
  312.         Tcl_SetVar(interp, "tcl_library", "", TCL_GLOBAL_ONLY);
  313.         Tcl_SetVar(interp, "tk_library", "", TCL_GLOBAL_ONLY);
  314.                                                                                 
  315.         // this seems just a hack, should NOT have hard-coded library path!
  316.         // why there's no problem with old  TCL/TK?
  317.         // xuanc, 10/3/2003
  318.         //Tcl_SetVar(interp, "tcl_library", "./lib/tcl8.0", TCL_GLOBAL_ONLY);
  319.         //Tcl_SetVar(interp, "tk_library", "./lib/tk8.0", TCL_GLOBAL_ONLY);
  320. #endif
  321. if (Otcl_Init(interp) == TCL_ERROR) {
  322. printf("%sn", interp->result);
  323. abort();
  324. }
  325. #ifdef HAVE_LIBTCLDBG
  326. if (Tcldbg_Init(interp) == TCL_ERROR) {
  327. return TCL_ERROR;
  328. }
  329. #endif
  330. Tcl::init(interp, appname);
  331. Tcl& tcl = Tcl::instance();
  332. tcl.evalf(display? "set argv "-name %s -display %s"" :
  333.    "set argv "-name %s"", 
  334.   appname, display, appname);
  335. Tk_Window tk = 0;
  336. #ifdef WIN32
  337. Tcl_SetVar(interp, "tcl_library", ".", TCL_GLOBAL_ONLY);
  338. Tcl_SetVar(interp, "tk_library", ".", TCL_GLOBAL_ONLY);
  339. #endif
  340. if (Tk_Init(tcl.interp()) == TCL_OK)
  341. tk = Tk_MainWindow(tcl.interp());
  342. if (tk == 0) {
  343. fprintf(stderr, "nam: %sn", interp->result);
  344. exit(1);
  345. }
  346. tcl.tkmain(tk);
  347. extern EmbeddedTcl et_tk, et_nam;
  348. et_tk.load();
  349. et_nam.load();
  350. int op;
  351. int cacheSize = 100;
  352. char* graphInput = new char[256];
  353. char* graphInterval = new char[256];
  354. char* buf = new char[256];
  355. char* args = new char[256];
  356. graphInput[0] = graphInterval[0] = buf[0] = args[0] = 0;
  357. while ((op = getopt(argc, (char**)argv, (char*)optstr)) != -1) {
  358. switch (op) {
  359. default:
  360. usage();
  361. case 'd':
  362. case 'N':
  363. /* already handled before */
  364. break;
  365. /*XXX move to Tcl */
  366. #ifdef notyet
  367. case 'M':
  368. tcl.add_option("movie", optarg);
  369. break;
  370. case 'p':
  371. tcl.add_option("pause", "1");
  372. break;
  373. case 'G':
  374. tcl.add_option("granularity", optarg);
  375. break;
  376. case 'X': {
  377. const char* value = parse_assignment(optarg);
  378. tcl.add_option(optarg, value);
  379. }
  380. break;
  381. case 'P':
  382. /* Peer name, obsoleted */
  383. sprintf(buf, "p %s ", optarg);
  384. strcat(args, buf);
  385. break;
  386. case 't':
  387. /* Use tkgraph. Must supply tkgraph input filename. */
  388. sprintf(graphInput, "g %s ", optarg);
  389. strcat(args, graphInput);
  390. break;
  391. #endif
  392. case 'a': 
  393. /* 
  394.  * Create a whole new instance.
  395.  */
  396. strcat(args, "a 1 ");
  397. break;
  398. case 'c':
  399. cacheSize = atoi(optarg);
  400. break;
  401. case 'f':
  402. case 'u':
  403. script = optarg;
  404. /* Also pass it to OTcl */
  405. sprintf(buf, "f %s ", optarg);
  406. strcat(args, buf);
  407. break;
  408. case 'g':
  409. process_geometry(tk, optarg);
  410. break;
  411. case 'i':
  412. /*
  413.  * Interval value for graph updates: default is
  414.  * set by nam_init.
  415.  */
  416. sprintf(graphInterval, "i %s ", optarg);
  417. strcat(args, graphInterval);
  418. break;
  419. case 'j':
  420. /* Initial startup time */
  421. sprintf(buf, "j %s ", optarg);
  422. strcat(args, buf);
  423. break;
  424. case 'k': 
  425. /* Initial socket port number */
  426. sprintf(buf, "k %s ", optarg);
  427. strcat(args, buf);
  428. break;
  429. case 'm':
  430. /* Multiple traces */
  431. /* no longer needed, but option is still allowed */
  432. /* for compatibility reasons */
  433. break;
  434. case 'r': 
  435. /* Initial animation rate */
  436. sprintf(buf, "r %s ", optarg);
  437. strcat(args, buf);
  438. break;
  439. case 's':
  440. /* synchronize all windows together */
  441. strcat(args, "s 1 ");
  442. break;
  443. case 'z': 
  444. /* set nam validation test on */
  445. strcat(args, "z 1 ");
  446. break;
  447. #ifndef WIN32
  448. case 'S':
  449. XSynchronize(Tk_Display(tk), True);
  450. break;
  451. #endif
  452. case 'x':
  453. pt.printLatex(stdout); 
  454. exit(0);
  455. break;
  456. case 'p':
  457. pt.print(stdout); 
  458. exit(0);
  459. break;
  460. }
  461. }
  462. if (strlen(graphInterval) && !strlen(graphInput)) {
  463. fprintf(stderr, "nam: missing graph input filen");
  464. exit(1);
  465. }
  466. loadbitmaps(interp);
  467. char* tracename = NULL; /* trace file */
  468. /*
  469.  * Linux libc-5.3.12 has a bug where if no arguments are processed
  470.  * optind stays at zero.  Work around that problem here.
  471.  * The work-around seems harmless in other OSes so it's not ifdef'ed.
  472.  */
  473. if ((optind == -1) || (optind == 0))
  474. optind = 1;
  475. /*
  476.  * Make sure the base name of the trace file
  477.  * was specified.
  478.  */
  479. // if (argc - optind < 1)
  480. // usage();
  481. tracename = argv[optind];
  482. //XXX need to port this
  483. #ifndef WIN32
  484. if ((tracename != NULL) ) {
  485. if (access(tracename, R_OK) < 0) {
  486. tracename = new char[strlen(argv[optind]) + 4];
  487. sprintf(tracename, "%s.nam", argv[optind]);
  488. }
  489. }
  490. #endif
  491. tcl.CreateCommand("adios", cmd_adios);
  492. tcl.CreateCommand("version", cmd_version);
  493. #ifdef WIN32
  494. platformInit(interp);
  495. #endif
  496. // XXX inappropriate to do initialization in this way?
  497. FILE *fp = fopen(".nam.tcl", "r");
  498. if (fp != NULL) {
  499. fclose(fp);
  500. tcl.EvalFile(".nam.tcl");
  501. }
  502. // User-supplied configuration files
  503. // option '-u' and '-f' are merged together
  504. // Evaluation is moved into OTcl
  505. //  if (script != NULL) {
  506. //  fp = fopen(script, "r");
  507. //  if (fp != NULL) {
  508. //  fclose(fp);
  509. //  tcl.EvalFile(script);
  510. //  } else {
  511. //  fprintf(stderr, "No configuration file %sn",
  512. //  script);
  513. //  }
  514. //  }
  515. Paint::init();
  516. State::init(cacheSize);
  517. // -- Start TclDebugger
  518. //Tcldbg_Init(interp);
  519. tcl.eval("set nam_local_display 0");
  520. if (tracename != NULL) {
  521. while (tracename) {
  522. // Any backslash characters in the filename must be
  523. // escaped before being passed to Tcl.
  524. char * new_tracename =
  525. (char*)malloc(2 * strlen(tracename) + 1);
  526. char * temp_tracename = new_tracename;
  527. while (*tracename) {
  528. if (*tracename == '\')
  529. *(temp_tracename++) = '\';
  530. *(temp_tracename++) = *tracename;
  531. ++tracename;
  532. }
  533. *temp_tracename = 0;
  534. tracename= new_tracename;
  535.  // Jump to nam-lib.tcl
  536. tcl.evalf("nam_init %s %s", tracename, args);
  537. tracename = argv[++optind];
  538. }
  539. } else {
  540. // Jump to nam-lib.tcl
  541. tcl.evalf("nam_init "" %s", args);
  542. }
  543.  
  544. tcl.eval("set nam_local_display");
  545. if (strcmp(tcl.result(),"1") == 0) {
  546. Tk_MainLoop();
  547. }
  548. return (0);
  549. }