commsfwtools/commstools/svg/parseseq.pl
branchRCL_3
changeset 18 9644881fedd0
parent 0 dfb7c4ff071f
equal deleted inserted replaced
17:9ddb1d67ebaf 18:9644881fedd0
    54 use strict;
    54 use strict;
    55 use Cwd;
    55 use Cwd;
    56 
    56 
    57 my $version = "2.2 (27/02/08)";
    57 my $version = "2.2 (27/02/08)";
    58 
    58 
    59 getopts("MHpx:N:A:vVr:R:hnf");
    59 getopts("MHpx:N:A:vVr:R:hnfo:");
    60 our($opt_M, $opt_H, $opt_p, $opt_x, $opt_N, $opt_A, $opt_v, $opt_V, $opt_r, $opt_R, $opt_h, $opt_n, $opt_f);
    60 our($opt_M, $opt_H, $opt_p, $opt_x, $opt_N, $opt_A, $opt_v, $opt_V, $opt_r, $opt_R, $opt_h, $opt_n, $opt_f, $opt_o);
       
    61 
       
    62 my $outputPath = processPathArgument($opt_o);
    61 
    63 
    62 if ($opt_h)
    64 if ($opt_h)
    63 {
    65 {
    64     print <<HELP;
    66     print <<HELP;
    65 Usage:
    67 Usage:
   120                             [4] AgentCPr :: PRStart
   122                             [4] AgentCPr :: PRStart
   121                             [5] AgentCPr :: CprDataClientStart
   123                             [5] AgentCPr :: CprDataClientStart
   122                             [6] AgentSCPr :: AgentSCprStart
   124                             [6] AgentSCPr :: AgentSCprStart
   123                             Select activity to draw:
   125                             Select activity to draw:
   124                             ...
   126                             ...
   125 			    
   127 
   126  -h                         This help message
   128 -o <path>					Place all output files into <path>/html/ directory (including log.html).
       
   129 
       
   130 -h                         This help message
   127 HELP
   131 HELP
   128     exit (0);
   132     exit (0);
   129 }
   133 }
   130 
   134 
   131 #
   135 #
   305 } else {
   309 } else {
   306 	my $viewsToDisplay = int($rowsToDisplay / $maxRowsToDisplay) + 1;
   310 	my $viewsToDisplay = int($rowsToDisplay / $maxRowsToDisplay) + 1;
   307 	my $rowsPerView = int(($rowsToDisplay + $viewsToDisplay - 1) / $viewsToDisplay);
   311 	my $rowsPerView = int(($rowsToDisplay + $viewsToDisplay - 1) / $viewsToDisplay);
   308 	my $viewNumber = 0;
   312 	my $viewNumber = 0;
   309 	createViewMap();
   313 	createViewMap();
       
   314 	createIpcMap();
   310 	while ($beginRow < $totalRows) {
   315 	while ($beginRow < $totalRows) {
   311 		$endRow = $beginRow + $rowsPerView - 1;
   316 		$endRow = $beginRow + $rowsPerView - 1;
   312 		if ($endRow >= $totalRows) {
   317 		if ($endRow >= $totalRows) {
   313 			drawView($beginRow, $totalRows - 1, $viewNumber, $viewNumber);	# last view
   318 			drawView($beginRow, $totalRows - 1, $viewNumber, $viewNumber);	# last view
   314 		} else {
   319 		} else {
   316 		}
   321 		}
   317 		++$viewNumber;
   322 		++$viewNumber;
   318 		$beginRow = $endRow + 1;
   323 		$beginRow = $endRow + 1;
   319 	}
   324 	}
   320 	closeViewMap($viewNumber);
   325 	closeViewMap($viewNumber);
       
   326 	closeIpcMap($viewNumber);
   321 }
   327 }
   322 
   328 
   323 print "\n" if ($opt_V);
   329 print "\n" if ($opt_V);
   324 
   330 
   325 if ($opt_v)
   331 if ($opt_v)
   351 	my $fileName = "log";
   357 	my $fileName = "log";
   352 	if ($viewNumber != $lastViewNumber) {
   358 	if ($viewNumber != $lastViewNumber) {
   353 		$fileName .= $viewNumber;
   359 		$fileName .= $viewNumber;
   354 		}
   360 		}
   355 
   361 
   356 	open SVG, ">html/${fileName}.svg" || die "Cannot open html/${fileName}.svg for writing\n";
   362 	my $path = $outputPath . "html/${fileName}.svg";
       
   363 	open SVG, ">$path" || die "Cannot open $path for writing\n";
   357 	#open RTTTL, ">html/${fileName}.rtttlpre" || die "Cannot open html/${fileName}.rttlpre for writing\n";
   364 	#open RTTTL, ">html/${fileName}.rtttlpre" || die "Cannot open html/${fileName}.rttlpre for writing\n";
   358 
   365 
   359 	outputDocHeader($screenWidth, $screenHeight);
   366 	outputDocHeader($screenWidth, $screenHeight);
   360 	drawObjectNames(0);
       
   361 	updateObjectViewList($viewNumber);
   367 	updateObjectViewList($viewNumber);
   362 	drawObjectLifelines($beginRow, $endRow, $screenHeight);
   368 	drawObjectLifelines($beginRow, $endRow, $screenHeight);
       
   369 	drawObjectNames(0);
   363 	drawActivities($beginRow, $endRow, $screenHeight, $viewNumber);
   370 	drawActivities($beginRow, $endRow, $screenHeight, $viewNumber);
   364 	my @labelsOnPage = ();
   371 	my @labelsOnPage = ();
   365 	my @objectsDestroyed = ();
   372 	my @objectsDestroyed = ();
   366 	my @objectsCreated = ();
   373 	my @objectsCreated = ();
   367 	drawSequences($beginRow, $endRow, 1, \@labelsOnPage, \@objectsCreated, \@objectsDestroyed);
   374 	my @ipc = ();
       
   375 	drawSequences($beginRow, $endRow, 1, \@labelsOnPage, \@objectsCreated, \@objectsDestroyed, \@ipc);
   368 	outputViewMap($viewNumber, $lastViewNumber, \@labelsOnPage, \@objectsCreated, \@objectsDestroyed);
   376 	outputViewMap($viewNumber, $lastViewNumber, \@labelsOnPage, \@objectsCreated, \@objectsDestroyed);
       
   377 	outputIpcMap($viewNumber, $lastViewNumber, \@ipc);
   369 	outputDocFooter();
   378 	outputDocFooter();
   370 
   379 
   371 	close SVG;
   380 	close SVG;
   372 	#close RTTTL;
   381 	#close RTTTL;
   373 
   382 
   377 	}
   386 	}
   378 
   387 
   379 	resetForNextView();
   388 	resetForNextView();
   380 }
   389 }
   381 
   390 
   382 sub createSubDir() {
   391 sub createSubDir()
   383 	if (! -d html) {
   392 {
   384 		mkdir "html" || die "Cannot create 'html' subdirectory\n";
   393 	my $path = $outputPath . "html"; 
       
   394 	if (! -d $path) {
       
   395 		mkdir $path || die "Cannot create $path subdirectory\n";
   385 	}
   396 	}
   386 }
   397 }
   387 sub resetForNextView() {
   398 sub resetForNextView() {
   388 	# objects to hide must be calculated afresh per view
   399 	# objects to hide must be calculated afresh per view
   389 	unhideAllObjects();
   400 	unhideAllObjects();
   944 			}
   955 			}
   945 		else
   956 		else
   946 			{
   957 			{
   947 			if ($i->{Order} == 0)
   958 			if ($i->{Order} == 0)
   948 				{
   959 				{
   949 				$colour = "";
   960 				$colour = "!";
   950 				}
   961 				}
   951 			else
   962 			else
   952 				{
   963 				{
   953 				$colour = (($i->{Order} % 2) == 0) ? $objectNameColour1 : $objectNameColour2;
   964 				$colour = (($i->{Order} % 2) == 0) ? $objectNameColour1 : $objectNameColour2;
       
   965 				$colour = "!" . $colour;
   954 				}
   966 				}
   955 			}
   967 			}
   956 		my $name = $i->{Name};
   968 		my $name = $i->{Name};
   957 		$name =~ s/^!//;
   969 		$name =~ s/^!//;
   958 		# **** REMOVE THIS HACK for debugEvent() ****
   970 		# **** REMOVE THIS HACK for debugEvent() ****
   965 			$colour =~ s/^!//;
   977 			$colour =~ s/^!//;
   966 		    outputText($x + $rotatedTextOffset, $name, $currentY, "begin", $colour, qq{id="$name" onclick="debugEvent(evt)" transform="$transform" font-size="12" font-family="sans-serif"});
   978 		    outputText($x + $rotatedTextOffset, $name, $currentY, "begin", $colour, qq{id="$name" onclick="debugEvent(evt)" transform="$transform" font-size="12" font-family="sans-serif"});
   967 		    }
   979 		    }
   968 		else
   980 		else
   969 		    {
   981 		    {
   970 		    outputText($i->{X}, $name, $currentY, "middle", $colour, qq{id="$name" onclick="debugEvent(evt)"});
   982 			my $stagger = ($i->{colno} & 1);
       
   983 		    outputText($i->{X}, $name, $currentY + ($stagger * $incrementY), "middle", $colour, qq{id="$name" onclick="debugEvent(evt)"});
   971 		    }
   984 		    }
   972 		} 
   985 		} 
   973 	incrementY();
   986 	incrementY(2);
   974 	}
   987 	}
   975 
   988 
   976 #
   989 #
   977 # Test whether a value is within a certain (start,end] range inclusive.
   990 # Test whether a value is within a certain (start,end] range inclusive.
   978 #
   991 #
  1135 #	Partitioning: how do popups work ?
  1148 #	Partitioning: how do popups work ?
  1136 #
  1149 #
  1137 
  1150 
  1138 sub drawSequences($$$$$$)
  1151 sub drawSequences($$$$$$)
  1139 	{
  1152 	{
  1140 	my ($startRow, $endRow, $drawFlag, $labelsOnPageRef, $objectsCreatedRef, $objectsDestroyedRef) = @_;
  1153 	my ($startRow, $endRow, $drawFlag, $labelsOnPageRef, $objectsCreatedRef, $objectsDestroyedRef, $ipcRef) = @_;
  1141 	my $nextLabel = "";
  1154 	my $nextLabel = "";
  1142 
  1155 
  1143 	# startRow/endRow = start/end row of displayed area (inclusive)
  1156 	# startRow/endRow = start/end row of displayed area (inclusive)
  1144 	# absoluteRow	  = increments through all rows that have an object to display, whether in displayed area or not.
  1157 	# absoluteRow	  = increments through all rows that have an object to display, whether in displayed area or not.
  1145 	# rows			  = Increments for each row that contains an object to display, but only when $absoluteRow moves
  1158 	# rows			  = Increments for each row that contains an object to display, but only when $absoluteRow moves
  1148 	my $rows = 0;
  1161 	my $rows = 0;
  1149 	my $absoluteRow = 0;
  1162 	my $absoluteRow = 0;
  1150 	my $drawDone = 0;
  1163 	my $drawDone = 0;
  1151 	my $inRange = 0;
  1164 	my $inRange = 0;
  1152 	my $lastPopupText = "";		# text of last "pn" action
  1165 	my $lastPopupText = "";		# text of last "pn" action
  1153 
       
  1154 	foreach my $ref (@sequences) {
  1166 	foreach my $ref (@sequences) {
  1155 		my $action = $ref->{Action};
  1167 		my $action = $ref->{Action};
  1156 
  1168 
  1157 		$inRange = IsInRangeInclusive($absoluteRow, $startRow, $endRow);
  1169 		$inRange = IsInRangeInclusive($absoluteRow, $startRow, $endRow);
  1158 		if ($action eq "t") {
  1170 		if ($action eq "t") {
  1167 					my $colour = "";
  1179 					my $colour = "";
  1168 					if ($text =~ /\s*\{(\d+,\d+,\d+)\}\s*(.+)/) {
  1180 					if ($text =~ /\s*\{(\d+,\d+,\d+)\}\s*(.+)/) {
  1169 						$colour .= "rgb($1)";
  1181 						$colour .= "rgb($1)";
  1170 						$text = $2;
  1182 						$text = $2;
  1171 					}
  1183 					}
  1172 					my $attrs = generatePopupAttrs(\$lastPopupText, qq{id="$ref->{Object}->{Name}"});
  1184 					my $name = $ref->{Object}->{Name};
       
  1185 					my $attrs = generatePopupAttrs(\$lastPopupText, qq{id="$name"});
  1173 					outputText($objX + $lifelineTextLeftMargin, $text, $currentY, "begin", $colour, $attrs);
  1186 					outputText($objX + $lifelineTextLeftMargin, $text, $currentY, "begin", $colour, $attrs);
  1174 					$drawDone = 1;
  1187 					$drawDone = 1;
  1175 					# support for putting threads into the view map
  1188 					# support for putting threads into the view map
  1176 					$text = $ref->{Text};
  1189 					$text = $ref->{Text};
  1177 					if ($text =~ m/^\(Thread "(.*)" (\w+)\)$/) {
  1190 					if ($text =~ m/^\(Thread "(.*)" (\w+)\)$/) {
  1178 						if ($2 eq "Created") {
  1191 						if ($2 eq "Created") {
  1179 							push @{$objectsCreatedRef}, $1;
  1192 							push @{$objectsCreatedRef}, $1;
  1180 						} elsif ($2 eq "Destroyed") {
  1193 						} elsif ($2 eq "Destroyed") {
  1181 							push @{$objectsDestroyedRef}, $1;
  1194 							push @{$objectsDestroyedRef}, $1;
  1182 						}
  1195 						}
       
  1196 					}
       
  1197 					if ($name =~ s/^!//) {
       
  1198 						push @{$ipcRef}, $ref;
  1183 					}
  1199 					}
  1184 				} else {
  1200 				} else {
  1185 					fakeUpCreationDeletionIfRequired($ref->{Object}, $absoluteRow);
  1201 					fakeUpCreationDeletionIfRequired($ref->{Object}, $absoluteRow);
  1186 					}
  1202 					}
  1187 				}
  1203 				}
  1382 			{
  1398 			{
  1383 			# Note: have (possibly) incremented absoluteRow above, so re-calculate $inRange
  1399 			# Note: have (possibly) incremented absoluteRow above, so re-calculate $inRange
  1384 			$inRange = IsInRangeInclusive($absoluteRow, $startRow, $endRow);
  1400 			$inRange = IsInRangeInclusive($absoluteRow, $startRow, $endRow);
  1385 			if ($inRange)
  1401 			if ($inRange)
  1386 				{
  1402 				{
  1387 				# drawObjectNames() increments Y once, and we increment Y once for
  1403 				# drawObjectNames() increments Y twice (for stagger), and we increment Y once for
  1388 				# spacing, so we occupy two rows here.
  1404 				# spacing, so we occupy three rows here.
  1389 				$rows += 2;
  1405 				$rows += 3;
  1390 				if ($drawFlag == 1)
  1406 				if ($drawFlag == 1)
  1391 					{
  1407 					{
  1392 					drawObjectNames(1);
  1408 					drawObjectNames(1);
  1393 					incrementY();
  1409 					incrementY();
  1394 					}
  1410 					}
  1395 				}
  1411 				}
  1396 			$absoluteRow += 2;
  1412 			$absoluteRow += 3;		# 2 + 1 for stagger
  1397 			}
  1413 			}
  1398 		}
  1414 		}
  1399 	return $rows;
  1415 	return $rows;
  1400 	}
  1416 	}
  1401 
  1417 
  1697 # HTML Embedder routines #
  1713 # HTML Embedder routines #
  1698 ##########################
  1714 ##########################
  1699 
  1715 
  1700 sub createViewMap()
  1716 sub createViewMap()
  1701 {
  1717 {
  1702 	open MAP, ">logmap.html" || die "Cannot open logmap.html for writing\n";
  1718 	my $path = $outputPath . "html/logmap.html";
       
  1719 	open MAP, ">$path" || die "Cannot open $path for writing\n";
  1703 	print MAP "<html>\n<body>\n";
  1720 	print MAP "<html>\n<body>\n";
  1704 	
  1721 	
  1705 	# Begin page label/time table
  1722 	# Begin page label/time table
  1706 	print MAP qq { <table border="1" style="text-align: center">\n };
  1723 	print MAP qq { <table border="1" style="text-align: center">\n };
  1707 	print MAP qq { <tr><th>Page</th><th colspan="2">Lines</th><th colspan="2">Times</th><th>Objects Created</th><th>Objects Destroyed</th></tr>\n };
  1724 	print MAP qq { <tr><th>Page</th><th colspan="2">Lines</th><th colspan="2">Times</th><th>Objects Created</th><th>Objects Destroyed</th></tr>\n };
  1828 			$obj->{LastPage} = $viewNumber;
  1845 			$obj->{LastPage} = $viewNumber;
  1829 		}
  1846 		}
  1830 	}
  1847 	}
  1831 }
  1848 }
  1832 
  1849 
       
  1850 sub createIpcMap()
       
  1851 {
       
  1852 	my $path = $outputPath . "html/ipcmap.html";
       
  1853 	open IPC, ">$path" || die "Cannot open $path for writing\n";
       
  1854 	print IPC "<html><head>\n";
       
  1855 	print IPC qq{<style type="text/css">};
       
  1856 	print IPC "td,th { text-align: left; font-family: courier new; white-space: nowrap ; font-size: smaller}\n";
       
  1857 	print IPC "</style></head><body>\n";
       
  1858 	
       
  1859 	# Begin page label/time table
       
  1860 	print IPC qq { <table border="1" >\n };
       
  1861 	print IPC qq { <tr><th style="text-align: center">Page</th><th style="text-align: center">EXEs...</th></tr>\n };
       
  1862 }
       
  1863 
       
  1864 sub closeIpcMap()
       
  1865 {
       
  1866 	print IPC "</table></body></html>\n";
       
  1867 	close IPC;
       
  1868 }
       
  1869 
       
  1870 my @IpcExeColumns = ();
       
  1871 
       
  1872 sub addToArrayUniquely($$)
       
  1873 {
       
  1874 	my ($arrRef, $element) = @_;
       
  1875 	foreach my $i ( @{$arrRef} ) {
       
  1876 		if ($i eq $element) {
       
  1877 			return;
       
  1878 		}
       
  1879 	}
       
  1880 	push @{$arrRef}, $element;
       
  1881 }
       
  1882 
       
  1883 sub outputIpcMap($$$)
       
  1884 {
       
  1885 	my ($viewNumber, $lastViewNumber, $ipcRef) = @_;
       
  1886 	my %ipcExeUsed = ();
       
  1887 	my $exe;
       
  1888 	my $ipc;
       
  1889 	foreach $ipc (@{$ipcRef}) {
       
  1890 		$exe = $ipc->{Object}->{Name};
       
  1891 		addToArrayUniquely(\@IpcExeColumns, $exe);
       
  1892 		$ipcExeUsed{$exe} = 1;
       
  1893 	}
       
  1894 	
       
  1895 	# Page number in first column (two rows)
       
  1896 	#my $style = qq{style="text-align: left; font-family: courier new; white-space: nowrap ; font-size: smaller"};
       
  1897 	print IPC qq {<tr><td rowspan="2" style="text-align: center">$viewNumber</td>\n};
       
  1898 	
       
  1899 	# Second and subsequent columns showing the exe names
       
  1900 	foreach $exe ( @IpcExeColumns ) {
       
  1901 		my $exe2 = $exe;			# why do things go wrong if I operate directly on $exe???
       
  1902 		$exe2 =~ s/^!//;
       
  1903 		if (!defined($ipcExeUsed{$exe})) {
       
  1904 			print IPC qq{<td style="text-align: center ; color: gray">$exe2</td>};
       
  1905 		} else {
       
  1906 			print IPC qq{<td style="text-align: center">$exe2</td>};
       
  1907 		}
       
  1908 	}
       
  1909 
       
  1910 	# next row
       
  1911 	print IPC qq{</tr>\n<tr>};
       
  1912 	# for each exe there is column...
       
  1913 	my $rr;
       
  1914 	foreach $rr ( @IpcExeColumns ) {
       
  1915 		print IPC qq{<td>};
       
  1916 		# ...showing the IPCs
       
  1917 		foreach my $ref ( @{$ipcRef} ) {
       
  1918 			if ($ref->{Object}->{Name} eq $rr) {
       
  1919 				print IPC qq{$ref->{Text}<br>};
       
  1920 			} else {
       
  1921 				print IPC qq{<br>};
       
  1922 			}
       
  1923 		}
       
  1924 		print IPC qq{</td>};
       
  1925 	}
       
  1926 	print IPC qq {</tr>\n};
       
  1927 }
  1833 
  1928 
  1834 #
  1929 #
  1835 # Output the "0 1 2 3 4 ..." anchors representing the different views
  1930 # Output the "0 1 2 3 4 ..." anchors representing the different views
  1836 #
  1931 #
  1837 sub outputHTMLPageLinks($$$$) {
  1932 sub outputHTMLPageLinks($$$$) {
  1845 				print HTML qq{&nbsp;<a href="${htmlPathNotLastView}log$i.html">$i</a>\n};
  1940 				print HTML qq{&nbsp;<a href="${htmlPathNotLastView}log$i.html">$i</a>\n};
  1846 			} else {
  1941 			} else {
  1847 				print HTML qq{&nbsp;<a href="${htmlPathLastView}log.html">$i</a>\n};
  1942 				print HTML qq{&nbsp;<a href="${htmlPathLastView}log.html">$i</a>\n};
  1848 			}
  1943 			}
  1849 		}
  1944 		}
       
  1945 	}
       
  1946 }
       
  1947 
       
  1948 sub processPathArgument($)
       
  1949 {
       
  1950 	my $path = $_[0];
       
  1951 	if ($path) {
       
  1952 		# ensure "/" at the end
       
  1953 		if ($path !~ /\/$/) {
       
  1954 			$path .= "/";
       
  1955 		}
       
  1956 		mkdirp($path);
       
  1957 		return $path;
       
  1958 	} else {
       
  1959 		return "";
       
  1960 	}
       
  1961 }
       
  1962 
       
  1963 sub mkdirp($) 
       
  1964 { 
       
  1965     my $dirName = @_[0]; 
       
  1966     if ($dirName =~ m/^(.*)\//i) { 
       
  1967         if ($1 ne "") { 
       
  1968             mkdirp($1); 
       
  1969         } 
       
  1970     } 
       
  1971 	if (! -d $dirName) {
       
  1972 		mkdir($dirName); 
  1850 	}
  1973 	}
  1851 }
  1974 }
  1852 
  1975 
  1853 sub outputHTMLEmbedder($$$$$)
  1976 sub outputHTMLEmbedder($$$$$)
  1854 {
  1977 {
  1872 		$htmlLinkPathLastView = "html/";
  1995 		$htmlLinkPathLastView = "html/";
  1873 		$htmlLinkPathNotLastView = "html/";
  1996 		$htmlLinkPathNotLastView = "html/";
  1874 		$svgPathInHtmlFile = "html/" . $fileName;
  1997 		$svgPathInHtmlFile = "html/" . $fileName;
  1875 		$mainPath = "";
  1998 		$mainPath = "";
  1876 	}
  1999 	}
  1877 	open HTML, ">${htmlPath}.html" || die "Cannot open ${htmlPath}.html for writing\n";
  2000 	my $path = $outputPath . $htmlPath . ".html";
       
  2001 	open HTML, ">$path" || die "Cannot open $path for writing\n";
  1878 
  2002 
  1879 	if (! $opt_f) {
  2003 	if (! $opt_f) {
  1880 		# DOCTYPE needed for "position: fixed" to work in IE 
  2004 		# DOCTYPE needed for "position: fixed" to work in IE 
  1881 		print HTML "<!--[if IE]>\n";
  2005 		print HTML "<!--[if IE]>\n";
  1882 		print HTML qq{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n};
  2006 		print HTML qq{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n};
  1915 		}
  2039 		}
  1916 
  2040 
  1917 	print HTML qq{<input type="button" value="Symbols" onclick="popupSymbols()">\n};
  2041 	print HTML qq{<input type="button" value="Symbols" onclick="popupSymbols()">\n};
  1918 	print HTML qq{<input type="button" value="Relations" onclick="popupRelations()">\n};
  2042 	print HTML qq{<input type="button" value="Relations" onclick="popupRelations()">\n};
  1919 	print HTML qq{<input type="button" value="Map" onclick="popupMap()">\n};
  2043 	print HTML qq{<input type="button" value="Map" onclick="popupMap()">\n};
       
  2044 	print HTML qq{<input type="button" value="IPC Map" onclick="popupIpcMap()">\n};
  1920 	print HTML qq{&nbsp;Zoom%\n<input type="text" size=3 maxlength=3 onkeypress="zoom(this,event)" />\n};
  2045 	print HTML qq{&nbsp;Zoom%\n<input type="text" size=3 maxlength=3 onkeypress="zoom(this,event)" />\n};
  1921 
  2046 
  1922 	if ($opt_f) {
  2047 	if ($opt_f) {
  1923 		# don't need the bottom page links if the fixed position ones are at the top
  2048 		# don't need the bottom page links if the fixed position ones are at the top
  1924 		outputHTMLPageLinks($viewNumber, $lastViewNumber, $htmlLinkPathNotLastView, $htmlLinkPathLastView);
  2049 		outputHTMLPageLinks($viewNumber, $lastViewNumber, $htmlLinkPathNotLastView, $htmlLinkPathLastView);
  2008 }
  2133 }
  2009 
  2134 
  2010 //
  2135 //
  2011 
  2136 
  2012 function popupSymbols() {
  2137 function popupSymbols() {
  2013 	symbols = window.open(mainPath + "logsym.html", "_blank", "width=400,resizable=yes,scrollbars=yes");
  2138 	symbols = window.open(mainPath + "html/logsym.html", "_blank", "width=400,resizable=yes,scrollbars=yes");
  2014 }
  2139 }
  2015 
  2140 
  2016 function popupRelations() {
  2141 function popupRelations() {
  2017 	relations = window.open(mainPath + "relations.html", "_blank", "resizable=yes,scrollbars=yes,status=yes");
  2142 	relations = window.open(mainPath + "html/relations.html", "_blank", "resizable=yes,scrollbars=yes,status=yes");
  2018 	relationsDefined = 1;
  2143 	relationsDefined = 1;
  2019 }
  2144 }
  2020 
  2145 
  2021 function popupMap() {
  2146 function popupMap() {
  2022 	relations = window.open(mainPath + "logmap.html", "_blank", "resizable=yes,scrollbars=yes,status=yes");
  2147 	relations = window.open(mainPath + "html/logmap.html", "_blank", "resizable=yes,scrollbars=yes,status=yes");
       
  2148 }
       
  2149 
       
  2150 function popupIpcMap() {
       
  2151 	relations = window.open(mainPath + "html/ipcmap.html", "_blank", "resizable=yes,scrollbars=yes,status=yes");
  2023 }
  2152 }
  2024 
  2153 
  2025 //
  2154 //
  2026 
  2155 
  2027 function objectHighlightForwarder(id) {
  2156 function objectHighlightForwarder(id) {