#########################################################################################
#			Cadence Design Systems						#
#											#
#			Command: displayDiffUI						#
#			Tcl File: cmDiffUtility.tcl					#
#											#
#			Author: Cadence Design Systems					#
#				Aditya Chandra						#
#			Email:  support@cadence.com					#
#				aditya@cadence.com					#
#			Creation Date: 06/22/2011					#
#											#
#########################################################################################
#											#
#	Copyright 2012 Cadence Design Systems, Inc.  All rights reserved.		#
#	Use of this code is restricted and is subject to the terms of the		#
#	existing license and/or services agreement between you and Cadence.		#
#	If you do not have an existing agreement with Cadence for the use		#
#	of this code, you may not use it.						#
#											#
#########################################################################################
#											#
#	06/22/2011: Cadence Constraints Differencing Utility				#
#	Revision history:								#
#	0.1 	Original file					June 22, 2011		#
#	0.7 	Support for more type of design files added 	July 26, 2012		#
#		along with improved error messages.					#
#	0.8 	Handled bugs reported by Sarbjit 		July 27, 2012		#
#	0.9 	Feedback on usability from Sarbjit handled.	July 28, 2012		#
#	1.0 	Corrected the "view" switch while running 	August 03, 2012		#
#		comparison between BE and FE.						#
#	1.1 	In case of Schematic & DCF file selection 	August 30, 2012		#
#		convert the files to Physical mode and then 				#
#		compare.								#
#	1.2	If both the databases are of same type, then	July 26, 2013		#
#		the report would mention them as DB1 & DB2. 				#
#		Check box option added for ignoring the 				#
#		difference reporting for EC Set Members. 	 			#
#		Changes for the above were made in 					#
#		cmfeedback.exe using the CCR# 1131724.					#
#	1.3	Change in the flag name for ignoreECSFlatten.	September 06, 2013	#
#		cmfeedback.exe Command line corrected in case 				#
#		the check box is unchecked. 						#
#	1.4	Changed the parameters in running cmfeedback 	February 14, 2014	#
#		during the F2B and B2F flows. Generate the DCF				#
#		file from the board file everytime there is a 				#
#		update in the board file.						#
#	1.5	UI has been updated to display all Valid file  	February 28, 2014	#
#		types initially for easier selection.					#
#	1.6	In case the selected DBs are schematic and  	February 28, 2014	#
#		board file, treat the differencing same as 				#
#		reported in F2B / B2F flow differeces. This is 				#
#		available in SPB 16.6 release onwards.					#
#	1.7	On clicking on the X, the application should 	March 21, 2014		#
#		exit.									#
#	1.8	Code fix for comparing two board files.		May 22, 2014		#
#	1.9	Code fix for issues reported by Sarbjit 	May 27, 2014		#
#	2.0	Removed the check box for EC Set Flatten	May 28, 2014		#
#	2.1	Code fix for CCR 1335501 			December 10, 2014	#
#	2.2	Changes made as per suggestions from Serge for 	January 28, 2015	#
#		two DCF files, use normal and not physical 				#
#		comparison. Also consolidated the function call 			#
#		to cmfeedback and start reporting error case.				#
#	2.3	Adding support for Changes Only / Overwrite 	March 16, 2015		#
#		Mode while running diff utility. 					#
#		Adding support for filter list for filtering 	 			#
#		out constraints which are not required.					#
#	2.4	Adding support for specifying the Filter File 	April 03, 2015		#
#		automatically based on the CPM file selected, 				#
#		or from enviornment variable or from 					#
#		pre-configured location in user HOME or in 				#
#		SITE area.								#
#	2.5	Handling pxl and netrev erros			May 21, 2015		#
#	2.6	Handling the case where the design is 		September 11, 2015	#
#		Read Only.								#
#	2.7	Addressing CCR 1353745:				September 30, 2015	#
#		  -Reporting errors in cmfeedback 					#
#		  -renamePhysical and consolidating the code				#
#		  -Running .cpm to .cpm comparison as 1vs2				#
#	2.8	Change in folder before running techfile	October 21, 2015	#
#		command to ensure that the folder is writeable				#
#		for generation of log files. 						#
#	2.9	Handled code for Readonly operations		November 16, 2015	#
#		Made some changes in UI to make the operations				#
#		more intutive.								#
#	3.01	Handled case when DCF files are in Read Only	November 23, 2015	#
#		folder.									#
#	3.1	Handled customer feedback around clearing of 	January 02, 2016	#
#		TEMP folder after process completion. Creation				#
#		of files in TEMP folder with PID information. 				#
#	3.11	Made minor change in File Deletion code.	January 04, 2016	#
#	3.2	Add check for Read Only fodler before running 	January 12, 2016	#
#		packager to ensure that packager run does not 				#
#		fail due to Read Only folder. Give a good				#
#		message to the user about the reason for 				#
#		failure.								#
#	3.3	Changing the utility to operate in Report Only	February 02, 2016	#
#		Mode for all comparison. All the files which 				#
#		were generated for comparison are now generated 			#
#		in temp folders and cleaned up after comparison				#
#		is completed.								#
#	3.4	While running B2F flowm change the folder to 	February 16, 2016	#
#		temp folder and then run the tools. 					#
#	3.5	The check for Read Only FE Design in F2B  	February 23, 2016	#
#		comparison is changed to checking of 					#
#		permissions of cpm file. 						#
#	3.6	If the selected databases are same, then 	February 24, 2016	#
#		error and do not compare the databases. 				#
#	3.7	Modified the check for same databases and 	February 25, 2016	#
#		added cleanup code when Close button is 				#
#		pressed.								#
#	3.8	Added Error Code to the error message after 	February 29, 2016	#
#		Rename Physical command. Modified the name 				#
#		of DCF file getting generated from the  				#
#		techfile command.							#
#	3.9	Enhanced the script to take command line 	May 31, 2016		#
#		arguments and operate in batch mode.					#
#		-mode									#
#			sch2brd	- Front to Back Flow					#
#			brd2sch	- Back to Front Flow					#
#			db2db	- Two files comparison mode				#
#		-db1		- First DB						#
#		-db2		- Second DB						#
#		-log		- Option to generate a log file 			#
#				  where the file name is specified 			#
#				  after this switch.					#
#		-reportFile  	- Name of the Diff Report which 			#
#				  would be generated on disk.				#
#		-filterFile	- Optional argument for the 				#
#				  Filter file.						#
#		-changesOnly  	- Optional argument for the Changes			#
#				  Only Mode. This would be applicable 			#
#				  only in F2B or B2F flows only. 			#
#		-showReport  	- Optional argument for displaying 			#
#				  the generated report. 				#
#	4.0	Support for tcfx file in command line added	August 03, 2016		#
#	4.1	Filter file was not getting honored when 	September 23, 2016	#
#		specified on command line. 						#
#		If the log file was not existing, then it was 				#
#		not getting generated. 							#
#		Added some new logging messages. 					#
#		Fixed the incorrect command line arguments				#
#	4.2	CCR# 1790106					August 28, 2017		#
#		Check for dcf file first in tbl_1 view, then 				#
#		in sch_1 view and then in constriants view. 				#
#		While comparing SCM design treat it as DB 				#
#		compare and not F2B or B2F compare.					#
#											#
#											#
#											#
#########################################################################################

set versionString "v4.2 - August 28, 2017"

set fileOne 0
set fileTwo 0
set lastPath ""
set genDCFFileList 0

set isTk [ info exists tk_version ]
if { $isTk == 1 } {
	catch { 
		wm withdraw .
		console show
	}
}

package require Tk

global tempFolder
set tempFolder 0
catch { set tempFolder $::env(TEMP) }
if { $tempFolder == 0 } {
	catch { set tempFolder $::env(TMP) }
	if { $tcl_platform(os) != "Windows NT" } {	
		set tempFolder "/tmp"
	}
}

global filesToBeDeleted
set filesToBeDeleted 0

proc selectCompDB { } {
	.diffUI.label_first_file configure -text "First File:"
	.diffUI.label_second_file configure -text "Second File:"
}

proc selectF2B { } {
	.diffUI.label_first_file configure -text "Schematic DB:"
	.diffUI.label_second_file configure -text "Layout DB:"
}

proc selectB2F { } {
	.diffUI.label_first_file configure -text "Layout DB:"
	.diffUI.label_second_file configure -text "Schematic DB:"
}

proc displayDiffUI { } {
	global versionString
	global firstFile
	global secondFile
	global fileOne
	global fileTwo
	global lastPath
	global genDCFFileList
	global filterFileBrowsed
	global tempFolder
	
	if { $tempFolder != "" } {
		if { [file writable $tempFolder] != 1 }	{
			tk_messageBox -message "The temp folder: $tempFolder is not writeable.\nPlease make sure that the temp folder has write permissions." \
					-title "Cadence Constraints Differencing Utility" -icon error -type ok
			exit
		}
	}
	
	set filterFileBrowsed 0
	set opeartion 0
	
	toplevel .diffUI
	wm title .diffUI "Cadence Constraints Differencing Utility - $versionString"
	wm protocol .diffUI WM_DELETE_WINDOW exit
	
	label .diffUI.label_empty1 	-text " "
	label .diffUI.label_empty2 	-text " "
	label .diffUI.label_empty3 	-text " "
	label .diffUI.label_empty4 	-text " "
	label .diffUI.label_title 	-text "Select Files for Comparison"
	
	radiobutton .diffUI.radiobutton_compare_dbs	-text "Compare Databases" -value "comp" -variable operation -indicatoron true -command selectCompDB
	radiobutton .diffUI.radiobutton_f2b_flow	-text "Front to Back Flow" -value "f2b" -variable operation -indicatoron true -command selectF2B
	radiobutton .diffUI.radiobutton_b2f_flow	-text "Back to Front Flow" -value "b2f" -variable operation -indicatoron true -command selectB2F
	
	.diffUI.radiobutton_compare_dbs select
		
	label .diffUI.label_first_file			-text "First File:" -justify left -height 2
	entry .diffUI.entry_first_file			-width 70 -relief sunken -bd 2 -textvariable firstFile
	button .diffUI.button_browse_first_file		-text "..." 

	label .diffUI.label_second_file			-text "Second File:" -justify left -height 2
	entry .diffUI.entry_second_file			-width 70 -relief sunken -bd 2 -textvariable secondFile
	button .diffUI.button_browse_second_file	-text "..." 

	label .diffUI.label_filter_file			-text "Filter Constraints File:" -justify left -height 2
	entry .diffUI.entry_filter_file			-width 70 -relief sunken -bd 2 -textvariable filterFile
	button .diffUI.button_browse_filter_file	-text "..."
	
	set filterFile [getFilterFile ""]
	.diffUI.entry_filter_file delete 0 end
	.diffUI.entry_filter_file insert 0 $filterFile
	
	checkbutton .diffUI.checkbutton_changes_only	-text "Run Changes-Only Comparison" -state disabled -variable changesOnly -anchor w -height 2
	.diffUI.checkbutton_changes_only deselect 		
	set changesOnly 0

	button .diffUI.button_compare			-text "Compare Files" -state disabled
	button .diffUI.button_close			-text "Close"

	grid  .diffUI.label_empty1			-row 0 -column 0
	
	grid .diffUI.radiobutton_compare_dbs		-row 1 -column 1 -sticky w
	grid .diffUI.radiobutton_f2b_flow		-row 1 -column 3 -sticky w
	grid .diffUI.radiobutton_b2f_flow		-row 1 -column 5 -sticky w
	
	grid  .diffUI.label_title			-row 2 -column 1 -columnspan 10

	grid .diffUI.label_first_file			-row 3 -column 1 -sticky w 
	grid .diffUI.entry_first_file			-row 3 -column 3 -sticky w -columnspan 6 
	grid .diffUI.button_browse_first_file		-row 3 -column 9 -sticky w -padx 4
	
	grid .diffUI.label_second_file			-row 4 -column 1 -sticky w 
	grid .diffUI.entry_second_file			-row 4 -column 3 -sticky w -columnspan 6 
	grid .diffUI.button_browse_second_file		-row 4 -column 9 -sticky w -padx 4
	
	grid .diffUI.label_filter_file         		-row 5 -column 1 -sticky w
	grid .diffUI.entry_filter_file         		-row 5 -column 3 -sticky w -columnspan 6 
	grid .diffUI.button_browse_filter_file		-row 5 -column 9 -sticky w -padx 4
	
	grid .diffUI.checkbutton_changes_only		-row 6 -column 1 -sticky w -columnspan 3
	
	grid .diffUI.button_compare			-row 7 -column 8 -sticky e
	grid .diffUI.button_close			-row 7 -column 9 -sticky w 
	
	grid  .diffUI.label_empty4			-row 8 -column 10
	
	set fileOne 0
	set fileTwo 0
	set extOne 0
	set extTwo 0
	
	bind .diffUI.button_browse_first_file <ButtonRelease> {
		set fileOne 0
		set initialDir "./"
		if { $firstFile != "" } {
			if { [file isdirectory $firstFile] == 1 } {
				set initialDir $firstFile
			} else {
				set initialDir [file dirname $firstFile]
			}
		} elseif { $secondFile != "" } {
			if { [file isdirectory $secondFile] == 1 } {
				set initialDir $secondFile
			} else {
				set initialDir [file dirname $secondFile]
			}
		} elseif { $lastPath != "" } {
			set initialDir $lastPath 
		}
		
		if { $operation == "f2b" } {
			set types { {"Schematic Projects" {.cpm} } {"All files" *} }
		} elseif { $operation == "b2f" } {
			set types { {"Design Files" {.brd .sip .mcm} } {"All files" *} }
		} else {
			set types { {"Valid Files" {.dcfx .dcf .tcfx .tcf .brd .sip .mcm .cpm} } {"Constraints Files" {.dcfx .dcf .tcfx .tcf} } {"Design Files" {.brd .sip .mcm} } {"Schematic Projects" {.cpm} } {"All files" *} }
		}
		
		set firstFile [tk_getOpenFile -filetypes $types -parent .diffUI -initialdir $initialDir]
		
		if { $firstFile != "" } {
			set lastPath [file dirname $firstFile]
		}
		
		set extOne [file extension $firstFile]
		if { $extOne == ".cpm" } {
			set cpmFileName $firstFile
			set cdsLibName [file join [file dirname $cpmFileName] cds.lib]
			set desName [exec -- cpmaccess -read $cpmFileName global design_name ]
			set libName [exec -- cpmaccess -read $cpmFileName global design_library ]
			
			set filePath 0
			set viewName "tbl_1"
			catch {
				set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf]]
			}
			if { $filePath == 0 } {
				set viewName "sch_1"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf]]
				}
			}
			if { $filePath == 0 } {
				set viewName "constraints"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf]]
				}
			}
			
			set fileOne $filePath
			if { $fileOne == 0 || [file exists $fileOne] == 0 } {
				tk_messageBox -message "Cannot find the constraints file in the schematic project: $cpmFileName.\nPlease select another schematic project." \
					-title "Cadence Constraints Differencing Utility" -icon error -type ok
			} else {
				set fileOne [renamePhysical $fileOne 1]
			}
		} elseif { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
			set brdFileName $firstFile
			set fileOne [file rootname $brdFileName]_1.dcf
			set generateDCF 1
			if { [file exists $fileOne] == 1 } {
				set brdTime [file mtime $brdFileName]
				set dcfTime [file mtime $fileOne]
				
				if { $dcfTime > $brdTime } {				
					set generateDCF 0
				}
			}
			
			if { $generateDCF == 1 } {
				set changeFolder 0
				set fileOne [file join $tempFolder "[file rootname [file tail $brdFileName]]_1_phys_[pid].dcf"]
				set changeFolder 1
				if { $filesToBeDeleted != 0 } {
					set filesToBeDeleted [lappend filesToBeDeleted $fileOne]
				} else {
					set filesToBeDeleted [list $fileOne]
				}

				processingMessage
				
				if { $changeFolder == 1 } {
					set oldFolder [pwd]
					cd $tempFolder
				}
				
				catch { exec -- techfile -w \"$brdFileName\" \"$fileOne\" }
				
				if { $changeFolder == 1 } {
					cd $oldFolder
				}
				
				destroy .diffUI.proMsg
				
				if { $genDCFFileList == 0 } {
					set genDCFFileList [list $fileOne]
				} else {
					set genDCFFileList [lappend genDCFFileList $fileOne]
				}
				
				if { [file exists $fileOne] == 0 } {
					tk_messageBox -message "Cannot generate the constraints file for the design: $brdFileName.\nPlease select another design file." \
						-title "Cadence Constraints Differencing Utility" -icon error -type ok
				}
			} else {
				tk_messageBox -message "Existing constraints file $fileOne will be used for the comparison." \
					-title "Cadence Constraints Differencing Utility" -icon warning -type ok		
			}
		} elseif { [ regexp {\.dcfx?$} $extOne ] } {
			set fileOne [renamePhysical $firstFile 1]
		} elseif { [ regexp {\.tcfx?$} $extOne ] } {
			set fileOne $firstFile
		}
		
		if { $fileOne != 0 && $fileTwo != 0 } {
			.diffUI.button_compare  configure -state normal
			
			if { $extOne == ".cpm" && $viewName != "tbl_1" } {
				if { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
					.diffUI.checkbutton_changes_only configure -state normal
					.diffUI.radiobutton_f2b_flow select
					selectF2B
				} else {
					.diffUI.checkbutton_changes_only configure -state disabled
				}
			} elseif { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
				if { $extTwo == ".cpm" && $viewName != "tbl_1" } {
					.diffUI.checkbutton_changes_only configure -state normal
					.diffUI.radiobutton_b2f_flow select
					selectB2F
				} else {
					.diffUI.checkbutton_changes_only configure -state disabled
				}
			}
		} else {
			.diffUI.button_compare  configure -state disabled
			.diffUI.checkbutton_changes_only configure -state disabled
		}
		set filterFile [getFilterFile $filterFile]
	}

	bind .diffUI.entry_first_file <FocusOut> {
		set fileOne 0
		set extOne [file extension $firstFile]
		if { $extOne == ".cpm" } {
			set cpmFileName $firstFile
			set cdsLibName [file join [file dirname $cpmFileName] cds.lib]
			set desName [exec -- cpmaccess -read $cpmFileName global design_name ]
			set libName [exec -- cpmaccess -read $cpmFileName global design_library ]
			
			set filePath 0
			set viewName "tbl_1"
			catch {
				set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
			}
			if { $filePath == 0 } {
				set viewName "sch_1"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
			if { $filePath == 0 } {
				set viewName "constraints"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
			
			set fileOne $filePath
			if { $fileOne == 0 || [file exists $fileOne] == 0 } {
				tk_messageBox -message "Cannot find the constraints file in the schematic project: $cpmFileName.\nPlease select another schematic project." \
					-title "Cadence Constraints Differencing Utility" -icon error -type ok
			} else {
				set fileOne [renamePhysical $fileOne 1]
			}
		} elseif { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
			set brdFileName $firstFile
			set fileOne [file rootname $brdFileName]_1.dcf
			set generateDCF 1
			if { [file exists $fileOne] == 1 } {
				set brdTime [file mtime $brdFileName]
				set dcfTime [file mtime $fileOne]
				
				if { $dcfTime > $brdTime } {				
					set generateDCF 0
				}
			}
			
			if { $generateDCF == 1 } {
				set changeFolder 0
				set fileOne [file join $tempFolder "[file rootname [file tail $brdFileName]]_1_phys_[pid].dcf"]
				set changeFolder 1
				if { $filesToBeDeleted != 0 } {
					set filesToBeDeleted [lappend filesToBeDeleted $fileOne]
				} else {
					set filesToBeDeleted [list $fileOne]
				}
				
				processingMessage
				
				if { $changeFolder == 1 } {
					set oldFolder [pwd]
					cd $tempFolder
				}
				
				catch { exec -- techfile -w \"$brdFileName\" \"$fileOne\" }
				
				if { $changeFolder == 1 } {
					cd $oldFolder
				}
				
				destroy .diffUI.proMsg
				
				if { $genDCFFileList == 0 } {
					set genDCFFileList [list $fileOne]
				} else {
					set genDCFFileList [lappend genDCFFileList $fileOne]
				}
				
				if { [file exists $fileOne] == 0 } {
					tk_messageBox -message "Cannot generate the constraints file for the design: $brdFileName.\nPlease select another design file." \
						-title "Cadence Constraints Differencing Utility" -icon error -type ok
				}
			} else {
				if { [lsearch $genDCFFileList $fileOne] == -1 } {
					tk_messageBox -message "Existing constraints file $fileOne will be used for the comparison." \
						-title "Cadence Constraints Differencing Utility" -icon warning -type ok
				}
			}
		} elseif { [ regexp {\.dcfx?$} $extOne ] } {
			set fileOne [renamePhysical $firstFile 1]
		} elseif { [ regexp {\.tcfx?$} $extOne ] } {
			set fileOne $firstFile
		}
		
		if { $fileOne != 0 && $fileTwo != 0 } {
			.diffUI.button_compare  configure -state normal
			
			if { $extOne == ".cpm" && $viewName != "tbl_1" } {
				if { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
					.diffUI.checkbutton_changes_only configure -state normal
					.diffUI.radiobutton_f2b_flow select
					selectF2B
				} else {
					.diffUI.checkbutton_changes_only configure -state disabled
				}
			} elseif { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
				if { $extTwo == ".cpm" && $viewName != "tbl_1" } {
					.diffUI.checkbutton_changes_only configure -state normal
					.diffUI.radiobutton_b2f_flow select
					selectB2F
				} else {
					.diffUI.checkbutton_changes_only configure -state disabled
				}
			}
		} else {
			.diffUI.button_compare  configure -state disabled
			.diffUI.checkbutton_changes_only configure -state disabled
		}
		set filterFile [getFilterFile $filterFile]
	}
	
	bind .diffUI.button_browse_second_file <ButtonRelease> {
		set fileTwo 0
		set initialDir "./"
		if { $secondFile != "" } {
			if { [file isdirectory $secondFile] == 1 } {
				set initialDir $secondFile
			} else {
				set initialDir [file dirname $secondFile]
			}
		} elseif { $firstFile != "" } {
			if { [file isdirectory $firstFile] == 1 } {
				set initialDir $firstFile
			} else {
				set initialDir [file dirname $firstFile]
			}
		} elseif { $lastPath != "" } {
			set initialDir $lastPath 
		}
		
		if { $operation == "f2b" } {
			set types { {"Design Files" {.brd .sip .mcm} } {"All files" *} }
		} elseif { $operation == "b2f" } {
			set types { {"Schematic Projects" {.cpm} } {"All files" *} }
		} else {
			set types { {"Valid Files" {.dcfx .dcf .tcfx .tcf .brd .sip .mcm .cpm} } {"Constraints Files" {.dcfx .dcf .tcfx .tcf} } {"Design Files" {.brd .sip .mcm} } {"Schematic Projects" {.cpm} } {"All files" *} }
		}
		
		set secondFile [tk_getOpenFile -filetypes $types -parent .diffUI -initialdir $initialDir]
		
		if { $secondFile != "" } {
			set lastPath [file dirname $secondFile]
		}
		
		set extTwo [file extension $secondFile]
		if { $extTwo == ".cpm" } {
			set cpmFileName $secondFile
			set cdsLibName [file join [file dirname $cpmFileName] cds.lib]
			set desName [exec -- cpmaccess -read $cpmFileName global design_name ]
			set libName [exec -- cpmaccess -read $cpmFileName global design_library ]
			
			set filePath 0
			set viewName "tbl_1"
			catch {
				set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
			}
			if { $filePath == 0 } {
				set viewName "sch_1"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
			if { $filePath == 0 } {
				set viewName "constraints"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
			
			set fileTwo $filePath
			if { $fileTwo == 0 || [file exists $fileTwo] == 0 } {
				tk_messageBox -message "Cannot find the constraints file in the schematic project: $cpmFileName.\nPlease select another schematic project." \
					-title "Cadence Constraints Differencing Utility" -icon error -type ok
			} else {
				set fileTwo [renamePhysical $fileTwo 2]
			}
		} elseif { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
			set brdFileName $secondFile
			set fileTwo [file rootname $brdFileName]_2.dcf
			set generateDCF 1
			if { [file exists $fileTwo] == 1 } {
				set brdTime [file mtime $brdFileName]
				set dcfTime [file mtime $fileTwo]
				
				if { $dcfTime > $brdTime } {				
					set generateDCF 0
				}
			}
			
			if { $generateDCF == 1 } {
				set changeFolder 0
				set fileTwo [file join $tempFolder "[file rootname [file tail $brdFileName]]_2_phys_[pid].dcf"]
				set changeFolder 1
				if { $filesToBeDeleted != 0 } {
					set filesToBeDeleted [lappend filesToBeDeleted $fileTwo]
				} else {
					set filesToBeDeleted [list $fileTwo]
				}
				
				processingMessage
				
				if { $changeFolder == 1 } {
					set oldFolder [pwd]
					cd $tempFolder
				}
				
				catch { exec -- techfile -w \"$brdFileName\" \"$fileTwo\" }
				
				if { $changeFolder == 1 } {
					cd $oldFolder
				}
				
				destroy .diffUI.proMsg
				
				if { $genDCFFileList == 0 } {
					set genDCFFileList [list $fileTwo]
				} else {
					set genDCFFileList [lappend genDCFFileList $fileTwo]
				}
				
				if { [file exists $fileTwo] == 0 } {
					tk_messageBox -message "Cannot generate the constraints file for the design: $brdFileName.\nPlease select another design file." \
						-title "Cadence Constraints Differencing Utility" -icon error -type ok
				}
			} else {
				tk_messageBox -message "Existing constraints file $fileTwo will be used for the comparison." \
					-title "Cadence Constraints Differencing Utility" -icon warning -type ok	
			}
		} elseif { [ regexp {\.dcfx?$} $extTwo ] } {
			set fileTwo [renamePhysical $secondFile 2]
		} elseif { [ regexp {\.tcfx?$} $extTwo ] } {
			set fileTwo $secondFile
		}
		
		if { $fileOne != 0 && $fileTwo != 0 } {
			.diffUI.button_compare  configure -state normal
			
			if { $extOne == ".cpm" && $viewName != "tbl_1" } {
				if { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
					.diffUI.checkbutton_changes_only configure -state normal
					.diffUI.radiobutton_f2b_flow select
					selectF2B
				} else {
					.diffUI.checkbutton_changes_only configure -state disabled
				}
			} elseif { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
				if { $extTwo == ".cpm" && $viewName != "tbl_1" } {
					.diffUI.checkbutton_changes_only configure -state normal
					.diffUI.radiobutton_b2f_flow select
					selectB2F
				} else {
					.diffUI.checkbutton_changes_only configure -state disabled
				}
			}
		} else {
			.diffUI.button_compare  configure -state disabled
			.diffUI.checkbutton_changes_only configure -state disabled
		}
		set filterFile [getFilterFile $filterFile]
	}
	
	bind .diffUI.entry_second_file <FocusOut> {
		set fileTwo 0
		set extTwo [file extension $secondFile]
		if { $extTwo == ".cpm" } {
			set cpmFileName $secondFile
			set cdsLibName [file join [file dirname $cpmFileName] cds.lib]
			set desName [exec -- cpmaccess -read $cpmFileName global design_name ]
			set libName [exec -- cpmaccess -read $cpmFileName global design_library ]
			
			set filePath 0
			set viewName "tbl_1"
			catch {
				set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
			}
			if { $filePath == 0 } {
				set viewName "sch_1"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
			if { $filePath == 0 } {
				set viewName "constraints"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
			
			set fileTwo $filePath
			if { $fileTwo == 0 || [file exists $fileTwo] == 0 } {
				tk_messageBox -message "Cannot find the constraints file in the schematic project: $cpmFileName.\nPlease select another schematic project." \
					-title "Cadence Constraints Differencing Utility" -icon error -type ok
			} else {
				set fileTwo [renamePhysical $fileTwo 2]
			}
		} elseif { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
			set brdFileName $secondFile
			set fileTwo [file rootname $brdFileName]_2.dcf
			set generateDCF 1
			if { [file exists $fileTwo] == 1 } {
				set brdTime [file mtime $brdFileName]
				set dcfTime [file mtime $fileTwo]
				
				if { $dcfTime > $brdTime } {				
					set generateDCF 0
				}
			}
			
			if { $generateDCF == 1 } {
				set changeFolder 0
				set fileTwo [file join $tempFolder "[file rootname [file tail $brdFileName]]_2_phys_[pid].dcf"]
				set changeFolder 1
				if { $filesToBeDeleted != 0 } {
					set filesToBeDeleted [lappend filesToBeDeleted $fileTwo]
				} else {
					set filesToBeDeleted [list $fileTwo]
				}
				
				processingMessage
				
				if { $changeFolder == 1 } {
					set oldFolder [pwd]
					cd $tempFolder
				}
				
				catch { exec -- techfile -w \"$brdFileName\" \"$fileTwo\" }
				
				if { $changeFolder == 1 } {
					cd $oldFolder
				}
				
				destroy .diffUI.proMsg
				
				if { $genDCFFileList == 0 } {
					set genDCFFileList [list $fileTwo]
				} else {
					set genDCFFileList [lappend genDCFFileList $fileTwo]
				}
				
				if { [file exists $fileTwo] == 0 } {
					tk_messageBox -message "Cannot generate the constraints file for the design: $brdFileName.\nPlease select another design file." \
						-title "Cadence Constraints Differencing Utility" -icon error -type ok
				}
			} else {
				if { [lsearch $genDCFFileList $fileTwo] == -1 } {
					tk_messageBox -message "Existing constraints file $fileTwo will be used for the comparison." \
						-title "Cadence Constraints Differencing Utility" -icon warning -type ok
				}
			}
		} elseif { [ regexp {\.dcfx?$} $extTwo ] } {
			set fileTwo [renamePhysical $secondFile 2]
		} elseif { [ regexp {\.tcfx?$} $extTwo ] } {
			set fileTwo $secondFile
		}
		
		if { $fileOne != 0 && $fileTwo != 0 } {
			.diffUI.button_compare  configure -state normal
			
			if { $extOne == ".cpm" && $viewName != "tbl_1" } {
				if { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
					.diffUI.checkbutton_changes_only configure -state normal
					.diffUI.radiobutton_f2b_flow select
					selectF2B
				} else {
					.diffUI.checkbutton_changes_only configure -state disabled
				}
			} elseif { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
				if { $extTwo == ".cpm" && $viewName != "tbl_1" } {
					.diffUI.checkbutton_changes_only configure -state normal
					.diffUI.radiobutton_b2f_flow select
					selectB2F
				} else {
					.diffUI.checkbutton_changes_only configure -state disabled
				}
			}
		} else {
			.diffUI.button_compare  configure -state disabled
			.diffUI.checkbutton_changes_only configure -state disabled
		}
		set filterFile [getFilterFile $filterFile]
	}
	
	bind .diffUI.button_browse_filter_file <ButtonRelease> {
		set initialDir "./"
		if { $secondFile != "" } {
			if { [file isdirectory $secondFile] == 1 } {
				set initialDir $secondFile
			} else {
				set initialDir [file dirname $secondFile]
			}
		} elseif { $firstFile != "" } {
			if { [file isdirectory $firstFile] == 1 } {
				set initialDir $firstFile
			} else {
				set initialDir [file dirname $firstFile]
			}
		} elseif { $lastPath != "" } {
			set initialDir $lastPath 
		}
		
		set types { {"Filter Files" {.txt} } {"All files" *} }
		set filterFile [tk_getOpenFile -filetypes $types -parent .diffUI -initialdir $initialDir]
		
		if { $filterFile != "" } {
			set lastPath [file dirname $secondFile]
			set filterFileBrowsed 1
		}
	}
	
	bind .diffUI.button_close <ButtonRelease> {
		if { $filesToBeDeleted != 0 } {
			foreach fileName $filesToBeDeleted {
				file delete -force -- $fileName
			}
		}
		exit
	}

	bind .diffUI.button_compare <ButtonRelease> {
		if { [string compare [file normalize $firstFile] [file normalize $secondFile]] == 0 } {
			tk_messageBox -message "Cannot specify same databases for comparison. Select two different databases for comparison." \
				-title "Cadence Constraints Differencing Utility" -icon error -type ok			
		} else {
			if { $filterFile != "" } {
				if { [file exists $filterFile] != 1 } {
					set filterFile ""
				}
			}
			
			if { $fileOne != 0 && $fileTwo != 0 } {
				if { $extOne == ".cpm"  && $viewName != "tbl_1" } {
					if { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
						compareF2B $cpmFileName $brdFileName $filterFile $changesOnly
						exit
					} elseif { $extTwo == ".cpm" } {
						runCmfeedback "1vs2" "in" $fileOne $fileTwo $filterFile $changesOnly
						exit
					}
				} elseif { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
					if { $extTwo == ".cpm"  && $viewName != "tbl_1" } {
						compareB2F $brdFileName $cpmFileName $filterFile $changesOnly
						exit
					} elseif { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
						runCmfeedback "1vs2" "in" $fileOne $fileTwo $filterFile $changesOnly
						exit
					}
				}
	
				runCmfeedback "1vs2" "in" $fileOne $fileTwo $filterFile $changesOnly
				exit
			}
		}
	}
}

proc renamePhysical { fileIn index } {		
	global tempFolder
	global filesToBeDeleted
	global logFile
	
	set changeFolder 0
	set phyFile [file join $tempFolder "[file tail $fileIn]_${index}_phys_[pid]"]
	set changeFolder 1
	if { $filesToBeDeleted != 0 } {
		set filesToBeDeleted [lappend filesToBeDeleted $phyFile]
	} else {
		set filesToBeDeleted [list $phyFile]
	}
	
	if { $changeFolder == 1 } {
		set oldFolder [pwd]
		cd $tempFolder
	}
	
	set rc [ catch { exec -- cmfeedback -renamePhysical $fileIn $phyFile } msg]
	set ec [lindex [split $::errorCode] end]

	if { $changeFolder == 1 } {
		cd $oldFolder
	}
	
	if { $ec == 2 } {
		return $fileIn
	} elseif { [file exists $phyFile] == 1 } {
		return $phyFile
	} else {
		if { $logFile == 0 } {
			tk_messageBox -message "Failed to generate the physical dcf file for $fileIn. Error Code: $ec - $msg\nReport may contain incorrect information." -title  "Cadence Constraints Differencing Utility" -icon error -type ok
		} else {
			reportMessage "Failed to generate the physical dcf file for $fileIn. Error Code: $ec - $msg\nReport may contain incorrect information."
		}
		return $fileIn
	}
}

proc compareB2F { brdFileName schProjName filterFile changesOnly} {
	global tempFolder
	global filesToBeDeleted
	
	if { [file exists $brdFileName] != 1 || [file exists $schProjName] != 1 } {
		if { $filesToBeDeleted != 0 } {
			foreach fileName $filesToBeDeleted {
				file delete -force -- $fileName
			}
		}
		return -1    
	}
	
	set cdsLibFile [file join [file dirname $schProjName] cds.lib]
	set cellName 0
	catch { set cellName [exec -- cpmaccess -read $schProjName global design_name ] }
	set libName 0
	catch { set libName [exec -- cpmaccess -read $schProjName global design_library ] }
	
	if { $libName == 0 || $cellName == 0 } {
		if { $filesToBeDeleted != 0 } {
			foreach fileName $filesToBeDeleted {
				file delete -force -- $fileName
			}
		}
		return -1
	}
	
	set cellFolder 0
	catch {set cellFolder [file normalize [ exec -- libaccess $cdsLibFile -path $libName $cellName ]]}
	
	if { $cellFolder == 0 } {
		if { $filesToBeDeleted != 0 } {
			foreach fileName $filesToBeDeleted {
				file delete -force -- $fileName
			}
		}
		return -1
	}
	
	set packagedFolder [file join $cellFolder packaged]
	set cmdbFile [file join $packagedFolder cmdbview.dat]
	
	set runGenfeed 1
	if { [file exists $cmdbFile] == 1 } {
		set cmdbFileTime [file mtime $cmdbFile]
		set brdFileTime [file mtime $brdFileName]
		if { $cmdbFileTime > $brdFileTime } {
			set runGenfeed 0
		}
	}
	
	set delFile 0
	if { $runGenfeed == 1 } {
		if { [file exists $packagedFolder] == 1 } {
			set packagedFolder [file join $tempFolder "packaged_[pid]"]
			set delFile 1
			if { [file exists $packagedFolder] == 0 } {
				file mkdir $packagedFolder
			}
		} else {
			set packagedFolder [file join $tempFolder "packaged_[pid]"]
			set delFile 1
			file mkdir $packagedFolder
		}
		
		set oldFolder [pwd]
		cd $tempFolder
		
		catch { exec -- genfeedformat -c -b $brdFileName -proj $schProjName -o $packagedFolder }
		
		cd $oldFolder
	}
	set cmdbFile [file join $packagedFolder cmdbview.dat]
	
	set dcfFile 0
	catch { set dcfFile [file normalize [ exec -- libaccess $cdsLibFile -path $libName $cellName sch_1 ${cellName}.dcf ]] }
	
	if { $dcfFile == 0 } {
		if { $filesToBeDeleted != 0 } {
			foreach fileName $filesToBeDeleted {
				file delete -force -- $fileName
			}
		}
		return -1
	}
	
	# puts "runCmfeedback \"physical\" \"in\" $dcfFile $cmdbFile $filterFile $changesOnly $packagedFolder \"-noComp\""
	runCmfeedback "physical" "in" $dcfFile $cmdbFile $filterFile $changesOnly $packagedFolder "-noComp"
	
	if { $delFile == 1 } {
		file delete -force -- $packagedFolder
	}
	if { $filesToBeDeleted != 0 } {
		foreach fileName $filesToBeDeleted {
			file delete -force -- $fileName
		}
	}
}

proc compareF2B { schProjName brdFileName filterFile changesOnly } {
	global tempFolder
	global filesToBeDeleted
	global logFile
	global reportFile
	global doNotShowReport
		
	if { [file exists $schProjName] != 1 || [file exists $brdFileName] != 1 } {
		return -1    
	}
	
	if { [file writable $schProjName] != 1 } { 
		if { $logFile == 0 } {
			tk_messageBox -message "Cannot compare the databases as packager can not be run on a Read Only design." -title "Cadence Constraints Differencing Utility" -icon error -type ok
		} else {
			reportMessage "Cannot compare the databases as packager can not be run on a Read Only design."
		}
		
		if { $filesToBeDeleted != 0 } {
			foreach fileName $filesToBeDeleted {
				file delete -force -- $fileName
			}
		}
		return -1
	}
	
	set cdsLibFile [file join [file dirname $schProjName] cds.lib]
	set cellName 0
	catch { set cellName [exec -- cpmaccess -read $schProjName global design_name ] }
	set libName 0
	catch { set libName [exec -- cpmaccess -read $schProjName global design_library ] }
	
	if { $libName == 0 || $cellName == 0 } {
		if { $filesToBeDeleted != 0 } {
			foreach fileName $filesToBeDeleted {
				file delete -force -- $fileName
			}
		}
		return -1
	}
	
	set cellFolder 0
	catch {set cellFolder [file normalize [ exec -- libaccess $cdsLibFile -path $libName $cellName ]]}
	
	if { $cellFolder == 0 } {
		if { $filesToBeDeleted != 0 } {
			foreach fileName $filesToBeDeleted {
				file delete -force -- $fileName
			}
		}
		return -1
	}
	
	set packagedFolder [file join $cellFolder packaged]
	set packagedFolderFile [file join $packagedFolder master.tag]
	if { [file exists $packagedFolderFile] == 1 } {
		set pkgTime [file mtime $packagedFolderFile]
		set schTime [file mtime [file join $cellFolder sch_1 master.tag]]
	} else {
		set pkgTime -1
		set schTime 0
	}
	
	if { $pkgTime < $schTime } {
		set curDir [pwd]
		cd [file dirname $schProjName]
		
		set curPackagedFolderName packaged
		catch { set curPackagedFolderName [exec -- cpmaccess -read $schProjName global view_packager ] }
		set tempPackagedFolderName "tmp_pkg_[pid]"
		set tmpPackagedFolder [file join $cellFolder $tempPackagedFolderName]
		
		exec -- cpmaccess -write $schProjName global view_packager $tempPackagedFolderName
		
		set rc [ catch { exec -- pxl -proj $schProjName }]

		exec -- cpmaccess -write $schProjName global view_packager $curPackagedFolderName
		
		cd $curDir
		if { $rc } {
			if { $logFile == 0 } { 
				tk_messageBox -message "$rc - Packaging of the design failed. See [file join $tmpPackagedFolder pxl.log] for details" -title "Cadence Constraints Differencing Utility" -icon error -type ok
			} else {
				reportMessage "$rc - Packaging of the design failed. See [file join $tmpPackagedFolder pxl.log] for details."
			}
			if { $filesToBeDeleted != 0 } {
				foreach fileName $filesToBeDeleted {
					file delete -force -- $fileName
				}
			}
			return -1
		}
	} else {
		set tmpPackagedFolder $packagedFolder
	}
	
	set outBrdFileName [file join $tempFolder "tmp_out_[pid].brd" ]
	set commandLineList [list netrev -i \"$tmpPackagedFolder\" -y 1 -a]
	
	if { $changesOnly == 0 } {
		set commandLineList [lappend commandLineList "-o"]
	}
	
	set commandLineList [lappend commandLineList \"$brdFileName\" \"$outBrdFileName\"]
	
	if { $reportFile == 0 } {
		set commandLineList [lappend commandLineList "-v"]
	} else {
		if { $doNotShowReport == 0 } {
			set commandLineList [lappend commandLineList "-w \"$reportFile\""]
		} else {
			set commandLineList [lappend commandLineList "-f \"$reportFile\""]
		}
	}
	
	if { $filterFile != "" } {
		set commandLineList [lappend commandLineList "-b" \"$filterFile\"]
	}
	
	set commandLine [join $commandLineList]
	# puts "$commandLine"
	catch { eval exec -- $commandLine } msg
	if { [string match "*No error detected*" $msg] == 0 } {
		set log [file join [file dirname $schProjName] netrev.lst]
		if { $logFile == 0 } {
			tk_messageBox -message "$msg\n\n\nSee $log for details" -title "Cadence Constraints Differencing Utility" -icon error -type ok
		} else {
			reportMessage "$msg\n\n\nSee $log for details"
		}
	}
	
	if { $tmpPackagedFolder != $packagedFolder } {
		file delete -force -- $tmpPackagedFolder
	}
	
	if { $filesToBeDeleted != 0 } {
		foreach fileName $filesToBeDeleted {
			file delete -force -- $fileName
		}
	}
	file delete -force -- $outBrdFileName 
}

proc runCmfeedback { view direction file1 file2 filterFile changesOnly { packagedFolder 0 } { nocomp 0 } } {
	global filesToBeDeleted
	global logFile
	global reportFile
	global doNotShowReport
	
	set commandLineList [list cmfeedback]
	
	if { $changesOnly == 1 } {
		set commandLineList [lappend commandLineList "-diff3"]
	} else {
		set commandLineList [lappend commandLineList "-overwrite"]
	}

	if { $nocomp != 0 } {
		set commandLineList [lappend commandLineList $nocomp]
	}
	
	if { $reportFile == 0 } {
		set commandLineList [lappend commandLineList "-Rx"]
	} else {
		if { $doNotShowReport == 0 } {
			set commandLineList [lappend commandLineList "-RZ \"$reportFile\""]
		} else {
			set commandLineList [lappend commandLineList "-RX \"$reportFile\""]
		}
	}
	
	if { [string length $filterFile] != 0 && $filterFile != "" } {
		set commandLineList [lappend commandLineList "-wl" \"$filterFile\"]
	}

	set commandLineList [lappend commandLineList $view $direction \"$file1\" \"$file2\"]
	
	if { $changesOnly == 1 } {
		set bc1 [file join $packagedFolder cmbcview.dat]
		set bc2 [file normalize $file1,p]
		set commandLineList [lappend commandLineList \"$bc1\" \"$bc2\"]
	}

	set commandLine [join $commandLineList]
	# puts "$commandLine "
	set rc [ catch { eval exec -- $commandLine } msg ]
	if { $rc != 0 } {
		regexp {[A-Z]+[ ][0-9]+[ ]([0-9]+)} $::errorCode full rc
	}
	
	if { $rc == 0 || $rc == 2 || $rc > 3 } {
		if { $logFile == 0 } {
			tk_messageBox -message "$msg" -title "Cadence Constraints Differencing Utility" -icon error -type ok
		} else {
			reportMessage "$msg"
		}
	}
	
	if { $filesToBeDeleted != 0 } {
		foreach fileName $filesToBeDeleted {
			file delete -force -- $fileName
		}
	}
}

proc processingMessage { } {
	toplevel .diffUI.proMsg
	wm title .diffUI.proMsg "Cadence Constraints Differencing Utility"
	
	label .diffUI.proMsg.label_empty1 	-text " 		"
	label .diffUI.proMsg.label_title	-text "Generating Constraints data from the Design data file..."
	label .diffUI.proMsg.label_empty2 	-text " 		"
	
	grid  .diffUI.proMsg.label_empty1	-row 1 -column 0 -columnspan 10
	grid  .diffUI.proMsg.label_title	-row 2 -column 1 -columnspan 10
	grid  .diffUI.proMsg.label_empty2	-row 3 -column 0 -columnspan 10
	
	wm deiconify .diffUI.proMsg 
	wm geometry .diffUI.proMsg 500x100
	update
}

proc comparingMessage { } {
	toplevel .diffUI.comMsg
	wm title .diffUI.comMsg "Cadence Constraints Differencing Utility"
	
	label .diffUI.comMsg.label_empty1 	-text " 		"
	label .diffUI.comMsg.label_title	-text "Comparing the two databases for Constraints differences..."
	label .diffUI.comMsg.label_empty2 	-text " 		"
	
	grid  .diffUI.comMsg.label_empty1	-row 1 -column 0 -columnspan 10
	grid  .diffUI.comMsg.label_title	-row 2 -column 1 -columnspan 10
	grid  .diffUI.comMsg.label_empty2	-row 3 -column 0 -columnspan 10
	
	wm deiconify .diffUI.comMsg 
	wm geometry .diffUI.comMsg 500x100
	update
}

proc getFilterFile { filterFile } {
	global firstFile
	global secondFile
	global filterFileBrowsed
	
	set filterFileName 0
	
	set HOME 0
	catch { set HOME $::env(HOME) }
	set SITE 0
	catch { set SITE $::env(CDS_SITE) }

	if { $filterFileBrowsed == 1 } {
		set filterFileName $filterFile
	}
	
	if { $filterFileName == 0 } {
		set envValue 0
		catch { set envValue $::env(CM_DIFF_UTILITY_PROP_FILTER_FILE) }
		if { $envValue != 0 } {
			if { [file isfile $envValue] == 1 } {
				if { [file exists $envValue] == 1 } {
					set filterFileName $envValue
				}
			} else {
				if { $HOME != 0 } {
					set fileName [file join $HOME cdssetup consmgr $envValue]
					if { [file exists $fileName] == 1 } {
						set filterFileName $fileName
					}
				}
				
				if { $filterFileName == 0 } {
					if { $SITE != 0 } {
						set fileName [file join $SITE cdssetup consmgr $envValue]
						if { [file exists $fileName] == 1 } {
							set filterFileName $fileName
						}
					}
				}
			}
		}
	}
	
	set envValue "propFilter.txt"
	if { $filterFileName == 0 } {
		if { $HOME != 0 } {
			set fileName [file join $HOME cdssetup consmgr $envValue]
			if { [file exists $fileName] == 1 } {
				set filterFileName $fileName
			}
		}
	}
	
	if { $filterFileName == 0 } {
		if { $SITE != 0 } {
			set fileName [file join $SITE cdssetup consmgr $envValue]
			if { [file exists $fileName] == 1 } {
				set filterFileName $fileName
			}
		}
	}
	
	if { $filterFileName == 0 } {
		if { [file extension $firstFile] == ".cpm" } {
			set fileName 0
			catch { set fileName [exec -- cpmaccess -read $firstFile CONSTRAINT_MGR CM_DIFF_UTILITY_PROP_FILTER_FILE] }
			if { [file exists $fileName] == 1 } {
				set filterFileName $fileName
			}
		}
	}
	
	if { $filterFileName == 0 } {
		if { [file extension $secondFile] == ".cpm" } {
			set fileName 0
			catch { set fileName [exec -- cpmaccess -read $secondFile CONSTRAINT_MGR CM_DIFF_UTILITY_PROP_FILTER_FILE] }
			if { [file exists $fileName] == 1 } {
				set filterFileName $fileName
			}
		}
	}

	if { $filterFileName == 0 } {	
		return "" 
	} else {
		return $filterFileName
	}
}

proc reportMessage { msg  } {
	global logFile
	
	puts "$msg"
	if { $logFile != 0 } {
		puts $logFile "$msg"
	}
}

proc callCMDiffUtility { opMode dbOne dbTwo logFileName { filterFileName 0 } { changesOnly 0 } } {
	global tempFolder
	global filesToBeDeleted
	global genDCFFileList
	global logFile
	global firstFile
	global secondFile
	
	set logFile 0
	if { $logFileName != 0 } {
		if { [file exists $logFileName] == 1 } {
			file delete -force -- $logFileName
		}
		set logFile [open $logFileName w]
	}
	
	if { [file exists $dbOne] != 1 } {
		reportMessage "Could not find the First DB file: $dbOne. Exiting..."
		if { $logFile != 0 } {
			close $logFile
		}
		exit
	}

	if { [file exists $dbTwo] != 1 } {
		reportMessage "Could not find the Second DB file: $dbTwo. Exiting..."
		if { $logFile != 0 } {
			close $logFile
		}
		exit
	}
	
	if { [string compare $dbOne $dbTwo] == 0 } {
		reportMessage "Cannot specify same databases for comparison. Select two different databases for comparison. Exiting..."
		if { $logFile != 0 } {
			close $logFile
		}
		exit
	}

	set firstFile $dbOne
	set secondFile $dbTwo
	if { $filterFileName == 0 } {
		set filterFile [getFilterFile ""]
		if { [file exists $filterFile] == 1 } {
			reportMessage "Using Filter file: $filterFile."
		} else {
			set filterFile ""
		}
	} else {
		set filterFile [getFilterFile $filterFileName]
		if { [file exists $filterFile] != 1 } {
			reportMessage "Could not find the Filter File: $filterFile. Continuing without the Filter file."
			set filterFile ""
		} else {
			reportMessage "Using Filter file: $filterFile."
		}
	}

	if { $changesOnly != 0 && $opMode == "db2db" } {
		reportMessage "Changes only mode is not applicable for Two Files Comparison mode. Ignoring the Changes Only mode and continuing."
	}
	
	set extOne [file extension $dbOne]
	set extTwo [file extension $dbTwo]
	if { $opMode == "sch2brd" } {
		if { $extOne == ".cpm" } {
			if { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
				set cpmFileName $dbOne
				set cdsLibName [file join [file dirname $cpmFileName] cds.lib]
				set desName [exec -- cpmaccess -read $cpmFileName global design_name ]
				set libName [exec -- cpmaccess -read $cpmFileName global design_library ]
				
				set filePath 0
				set viewName "tbl_1"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
				if { $filePath == 0 } {
					set viewName "sch_1"
					catch {
						set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
					}
				}
				if { $filePath == 0 } {
					set viewName "constraints"
					catch {
						set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
					}
				}
				
				set fileOne $filePath
				if { $fileOne == 0 || [file exists $fileOne] == 0 } {
					reportMessage "Cannot find the constraints file in the schematic project: $cpmFileName. Exiting..."
					if { $logFile != 0 } {
						close $logFile
					}
					exit
				} else {
					set fileOne [renamePhysical $fileOne 1]
				}
				
				set brdFileName $dbTwo
				set fileTwo [file join $tempFolder "[file rootname [file tail $brdFileName]]_2_phys_[pid].dcf"]
				if { $filesToBeDeleted != 0 } {
					set filesToBeDeleted [lappend filesToBeDeleted $fileTwo]
				} else {
					set filesToBeDeleted [list $fileTwo]
				}
				
				set oldFolder [pwd]
				cd $tempFolder
				catch { exec -- techfile -w \"$brdFileName\" \"$fileTwo\" }
				cd $oldFolder
				
				if { $genDCFFileList == 0 } {
					set genDCFFileList [list $fileTwo]
				} else {
					set genDCFFileList [lappend genDCFFileList $fileTwo]
				}
					
				if { [file exists $fileTwo] == 0 } {
					reportMessage "Cannot generate the constraints file for the design: $brdFileName. Exiting..."
					if { $logFile != 0 } {
						close $logFile
					}
					exit
				}
			} else {
				reportMessage "The operation mode \'sch2brd\' requires first DB to be a schematic and the second DB to be a layout file. Exiting..."
				if { $logFile != 0 } {
					close $logFile
				}
				exit
			}
		} else {
			reportMessage "The operation mode \'sch2brd\' requires first DB to be a schematic and the second DB to be a layout file. Exiting..."
			if { $logFile != 0 } {
				close $logFile
			}
			exit
		}
	} elseif { $opMode == "brd2sch" } {
		if { $extTwo == ".cpm" } {
			if { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
				set cpmFileName $dbTwo
				set cdsLibName [file join [file dirname $cpmFileName] cds.lib]
				set desName [exec -- cpmaccess -read $cpmFileName global design_name ]
				set libName [exec -- cpmaccess -read $cpmFileName global design_library ]
				
				set filePath 0
				set viewName "tbl_1"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
				if { $filePath == 0 } {
					set viewName "sch_1"
					catch {
						set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
					}
				}
				if { $filePath == 0 } {
					set viewName "constraints"
					catch {
						set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
					}
				}
				
				set fileTwo $filePath
				if { $fileTwo == 0 || [file exists $fileTwo] == 0 } {
					reportMessage "Cannot find the constraints file in the schematic project: $cpmFileName. Exiting..."
					if { $logFile != 0 } {
						close $logFile
					}
					exit
				} else {
					set fileTwo [renamePhysical $fileTwo 2]
				}
				
				set brdFileName $dbOne
				set fileOne [file join $tempFolder "[file rootname [file tail $brdFileName]]_1_phys_[pid].dcf"]
				if { $filesToBeDeleted != 0 } {
					set filesToBeDeleted [lappend filesToBeDeleted $fileOne]
				} else {
					set filesToBeDeleted [list $fileOne]
				}
				
				set oldFolder [pwd]
				cd $tempFolder
				catch { exec -- techfile -w \"$brdFileName\" \"$fileOne\" }
				cd $oldFolder
				
				if { $genDCFFileList == 0 } {
					set genDCFFileList [list $fileOne]
				} else {
					set genDCFFileList [lappend genDCFFileList $fileOne]
				}
					
				if { [file exists $fileOne] == 0 } {
					reportMessage "Cannot generate the constraints file for the design: $brdFileName. Exiting..."
					if { $logFile != 0 } {
						close $logFile
					}
					exit
				}
			} else {
				reportMessage "The operation mode \'brd2sch\' requires first DB to be a layout file and the second DB to be a schematic. Exiting..."
				if { $logFile != 0 } {
					close $logFile
				}
				exit
			}
		} else {
			reportMessage "The operation mode \'brd2sch\' requires first DB to be a layout file and the second DB to be a schematic. Exiting..."
			if { $logFile != 0 } {
				close $logFile
			}
			exit
		}
	} else {	# $opMode == "db2db"
		if { $extOne == ".cpm" } {
			set cpmFileName $dbOne
			set cdsLibName [file join [file dirname $cpmFileName] cds.lib]
			set desName [exec -- cpmaccess -read $cpmFileName global design_name ]
			set libName [exec -- cpmaccess -read $cpmFileName global design_library ]
			
			set filePath 0
			set viewName "tbl_1"
			catch {
				set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
			}
			if { $filePath == 0 } {
				set viewName "sch_1"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
			if { $filePath == 0 } {
				set viewName "constraints"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
			
			set fileOne $filePath
			if { $fileOne == 0 || [file exists $fileOne] == 0 } {
				reportMessage "Cannot find the constraints file in the schematic project: $cpmFileName. Exiting..."
				if { $logFile != 0 } {
					close $logFile
				}
				exit
			} else {
				set fileOne [renamePhysical $fileOne 1]
			}
		} elseif { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
			set brdFileName $dbOne
			set fileOne [file join $tempFolder "[file rootname [file tail $brdFileName]]_1_phys_[pid].dcf"]
			if { $filesToBeDeleted != 0 } {
				set filesToBeDeleted [lappend filesToBeDeleted $fileOne]
			} else {
				set filesToBeDeleted [list $fileOne]
			}
			
			set oldFolder [pwd]
			cd $tempFolder
			catch { exec -- techfile -w \"$brdFileName\" \"$fileOne\" }
			cd $oldFolder
			
			if { $genDCFFileList == 0 } {
				set genDCFFileList [list $fileOne]
			} else {
				set genDCFFileList [lappend genDCFFileList $fileOne]
			}
				
			if { [file exists $fileOne] == 0 } {
				reportMessage "Cannot generate the constraints file for the design: $brdFileName. Exiting..."
				if { $logFile != 0 } {
					close $logFile
				}
				exit
			}
		} elseif { [ regexp {\.dcfx?$} $extTwo ] } {
			set fileOne [renamePhysical $dbOne 1]
		} elseif { [ regexp {\.tcfx?$} $extTwo ] } {
			set fileOne $dbOne
		}
		
		if { $extTwo == ".cpm" } {
			set cpmFileName $dbTwo
			set cdsLibName [file join [file dirname $cpmFileName] cds.lib]
			set desName [exec -- cpmaccess -read $cpmFileName global design_name ]
			set libName [exec -- cpmaccess -read $cpmFileName global design_library ]
			
			set filePath 0
			set viewName "tbl_1"
			catch {
				set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
			}
			if { $filePath == 0 } {
				set viewName "sch_1"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
			if { $filePath == 0 } {
				set viewName "constraints"
				catch {
					set filePath [file normalize [ exec -- libaccess $cdsLibName -path $libName $desName $viewName $desName.dcf ]]
				}
			}
		
			set fileTwo $filePath
			if { $fileTwo == 0 || [file exists $fileTwo] == 0 } {
				reportMessage "Cannot find the constraints file in the schematic project: $cpmFileName. Exiting..."
				if { $logFile != 0 } {
					close $logFile
				}
				exit
			} else {
				set fileTwo [renamePhysical $fileTwo 2]
			}
		} elseif { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
			set brdFileName $dbTwo
			set fileTwo [file join $tempFolder "[file rootname [file tail $brdFileName]]_2_phys_[pid].dcf"]
			if { $filesToBeDeleted != 0 } {
				set filesToBeDeleted [lappend filesToBeDeleted $fileTwo]
			} else {
				set filesToBeDeleted [list $fileTwo]
			}
			
			set oldFolder [pwd]
			cd $tempFolder
			catch { exec -- techfile -w \"$brdFileName\" \"$fileTwo\" }
			cd $oldFolder
			
			if { $genDCFFileList == 0 } {
				set genDCFFileList [list $fileTwo]
			} else {
				set genDCFFileList [lappend genDCFFileList $fileTwo]
			}
				
			if { [file exists $fileTwo] == 0 } {
				reportMessage "Cannot generate the constraints file for the design: $brdFileName. Exiting..."
				if { $logFile != 0 } {
					close $logFile
				}
				exit
			}
		} elseif { [ regexp {\.dcfx?$} $extTwo ] } {
			set fileTwo [renamePhysical $dbTwo 2]
		} elseif { [ regexp {\.tcfx?$} $extTwo ] } {
			set fileTwo $dbTwo
		}
	}
	
	if { $fileOne != 0 && $fileTwo != 0 } {
		if { $extOne == ".cpm" && $viewName != "tbl_1" } {
			if { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
				reportMessage "Comparing schematic database $cpmFileName with board database $brdFileName."
				compareF2B $cpmFileName $brdFileName $filterFile $changesOnly
				exit
			} elseif { $extTwo == ".cpm" } {
				reportMessage "Comparing schematic database $fileOne with scheamtic database $fileTwo."
				runCmfeedback "1vs2" "in" $fileOne $fileTwo $filterFile $changesOnly
				exit
			}
		} elseif { $extOne == ".brd" || $extOne == ".sip" || $extOne == ".mcm" } {
			if { $extTwo == ".cpm" && $viewName != "tbl_1" } {
				reportMessage "Comparing board database $brdFileName with schematic database $cpmFileName."
				compareB2F $brdFileName $cpmFileName $filterFile $changesOnly
				exit
			} elseif { $extTwo == ".brd" || $extTwo == ".sip" || $extTwo == ".mcm" } {
				reportMessage "Comparing board database $fileOne with board database $fileTwo."
				runCmfeedback "1vs2" "in" $fileOne $fileTwo $filterFile $changesOnly
				exit
			}
		}
	
		reportMessage "Comparing database $fileOne with database $fileTwo."
		runCmfeedback "1vs2" "in" $fileOne $fileTwo $filterFile $changesOnly
	}
}

proc printCmdLine { } {
	global versionString
	reportMessage " "
	reportMessage "Cadence Constraints Differencing Utility - $versionString"
	reportMessage "Usage: cmDiffUtility \[ -mode sch2brd | brd2sch | db2db -db1 <db1Name> -db2 <db2Name> \[-reportFile <reportFileName>\] \[-log <logFileName>\] \[-filterFile <filterFileName>\] \[-changesOnly\] \[-showReport\] \]"
	reportMessage " Options:"
	reportMessage " 	No Arguments - Start in UI Mode"
	reportMessage "	-mode "
	reportMessage "		sch2brd		- Front to Back Flow"
	reportMessage "		brd2sch		- Back to Front Flow"
	reportMessage "		db2db		- Two files comparison mode"
	reportMessage "	-db1			- First DB"
	reportMessage "	-db2			- Second DB"
	reportMessage "	-reportFile		- Option to specify the name of the Diff Report which would be generated on disk. The generated report file is an XML file."
	reportMessage "					  If this is not set then report is displayed."
	reportMessage "	-log			- Option to generate a log file where the file name is specified after this switch"
	reportMessage "	-filterFile   	- Optional argument for the Filter file."
	reportMessage "	-changesOnly  	- Optional argument for the Changes Only Mode. This would be applicable only in F2B or B2F flows only."
	reportMessage "	-showReport  	- Optional argument for displaying the generated report."
	reportMessage " "
}

global reportFile
global doNotShowReport
global filterFileBrowsed
set filterFileBrowsed 0

set opMode 0
set dbOne 0
set dbTwo 0
set reportFile 0
set logFile 0
set filterFile 0
set changesOnly 0
set doNotShowReport 1

catch { console hide }

if { $argc == 0 } {
	displayDiffUI
} elseif { $argc > 1 } {
	set index 0
	while { $index < $argc } {
		set arg [lindex $argv $index]
		incr index
		if { $arg == "-mode" } {
			set opMode [lindex $argv $index]
			if { [lsearch [list "sch2brd" "brd2sch" "db2db"] $opMode] == -1 } {
				printCmdLine
				exit
			}
			incr index
		} elseif { $arg == "-db1" } {
		    set dbOne [file normalize [lindex $argv $index]]
		    incr index
		} elseif { $arg == "-db2" } {
		    set dbTwo [file normalize [lindex $argv $index]]
		    incr index
		} elseif { $arg == "-reportFile" } {
		    set reportFile [file normalize [lindex $argv $index]]
		    incr index
		} elseif { $arg == "-log" } {
		    set logFile [file normalize [lindex $argv $index]]
		    incr index
		} elseif { $arg == "-filterFile" } {
		    set filterFile [file normalize [lindex $argv $index]]
		    incr index
		    set filterFileBrowsed 1
		} elseif { $arg == "-changesOnly" } {
		    set changesOnly 1
		} elseif { $arg == "-showReport" } {
		    set doNotShowReport 0
		} else {
			printCmdLine
			exit
		}
	}
	
	if { $opMode != 0 && $dbOne != 0 && $dbTwo != 0 } {
		callCMDiffUtility $opMode $dbOne $dbTwo $logFile $filterFile $changesOnly
	} else {
		printCmdLine
	}
	exit	
} else {
	printCmdLine
	exit
}
