| 
									
										
										
										
											1996-11-27 19:52:01 +00:00
										 |  |  | #! /usr/bin/env python | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # A window-oriented recursive diff utility. | 
					
						
							|  |  |  | # NB: This uses undocumented window classing modules. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # TO DO: | 
					
						
							|  |  |  | #	- faster update after moving/copying one file | 
					
						
							|  |  |  | #	- diff flags (-b, etc.) should be global or maintained per window | 
					
						
							|  |  |  | #	- use a few fixed windows instead of creating new ones all the time | 
					
						
							|  |  |  | #	- ways to specify patterns to skip | 
					
						
							|  |  |  | #	  (best by pointing at a file and clicking a special menu entry!) | 
					
						
							|  |  |  | #	- add rcsdiff menu commands | 
					
						
							|  |  |  | #	- add a way to view status of selected files without opening them | 
					
						
							|  |  |  | #	- add a way to diff two files with different names | 
					
						
							|  |  |  | #	- add a way to rename files | 
					
						
							|  |  |  | #	- keep backups of overwritten/deleted files | 
					
						
							|  |  |  | #	- a way to mark specified files as uninteresting for dircmp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import rand | 
					
						
							|  |  |  | import commands | 
					
						
							|  |  |  | import dircache | 
					
						
							|  |  |  | import statcache | 
					
						
							|  |  |  | import cmp | 
					
						
							|  |  |  | import cmpcache | 
					
						
							|  |  |  | import stdwin | 
					
						
							|  |  |  | import gwin | 
					
						
							|  |  |  | import textwin | 
					
						
							|  |  |  | import filewin | 
					
						
							|  |  |  | import tablewin | 
					
						
							|  |  |  | import anywin | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | mkarg = commands.mkarg | 
					
						
							|  |  |  | mk2arg = commands.mk2arg | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # List of names to ignore in dircmp() | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1995-07-10 11:58:31 +00:00
										 |  |  | skiplist = ['RCS', 'CVS', '.Amake', 'tags', 'TAGS', '.', '..'] | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Function to determine whether a name should be ignored in dircmp(). | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def skipthis(file): | 
					
						
							|  |  |  | 	return file[-1:] == '~' or file in skiplist | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def anydiff(a, b, flags): # Display differences between any two objects | 
					
						
							|  |  |  | 	print 'diff', flags, a, b | 
					
						
							|  |  |  | 	if os.path.isdir(a) and os.path.isdir(b): | 
					
						
							|  |  |  | 		w = dirdiff(a, b, flags) | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		w = filediff(a, b, flags) | 
					
						
							|  |  |  | 	addstatmenu(w, [a, b]) | 
					
						
							|  |  |  | 	w.original_close = w.close | 
					
						
							|  |  |  | 	w.close = close_dirwin | 
					
						
							|  |  |  | 	return w | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def close_dirwin(w): | 
					
						
							|  |  |  | 	close_subwindows(w, (), 0) | 
					
						
							|  |  |  | 	w.original_close(w) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def filediff(a, b, flags): # Display differences between two text files | 
					
						
							|  |  |  | 	diffcmd = 'diff' | 
					
						
							|  |  |  | 	if flags: diffcmd = diffcmd + mkarg(flags) | 
					
						
							|  |  |  | 	diffcmd = diffcmd + mkarg(a) + mkarg(b) | 
					
						
							|  |  |  | 	difftext = commands.getoutput(diffcmd) | 
					
						
							|  |  |  | 	return textwin.open_readonly(mktitle(a, b), difftext) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def dirdiff(a, b, flags): # Display differences between two directories | 
					
						
							|  |  |  | 	data = diffdata(a, b, flags) | 
					
						
							|  |  |  | 	w = tablewin.open(mktitle(a, b), data) | 
					
						
							|  |  |  | 	w.flags = flags | 
					
						
							|  |  |  | 	w.a = a | 
					
						
							|  |  |  | 	w.b = b | 
					
						
							|  |  |  | 	addviewmenu(w) | 
					
						
							|  |  |  | 	addactionmenu(w) | 
					
						
							|  |  |  | 	return w | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def diffdata(a, b, flags): # Compute directory differences. | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	a_only = [('A only:', header_action), ('', header_action)] | 
					
						
							|  |  |  | 	b_only = [('B only:', header_action), ('', header_action)] | 
					
						
							|  |  |  | 	ab_diff = [('A <> B:', header_action), ('', header_action)] | 
					
						
							|  |  |  | 	ab_same = [('A == B:', header_action), ('', header_action)] | 
					
						
							|  |  |  | 	data = [a_only, b_only, ab_diff, ab_same] | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	a_list = dircache.listdir(a)[:] | 
					
						
							|  |  |  | 	b_list = dircache.listdir(b)[:] | 
					
						
							|  |  |  | 	dircache.annotate(a, a_list) | 
					
						
							|  |  |  | 	dircache.annotate(b, b_list) | 
					
						
							|  |  |  | 	a_list.sort() | 
					
						
							|  |  |  | 	b_list.sort() | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	for x in a_list: | 
					
						
							|  |  |  | 		if x in ['./', '../']: | 
					
						
							|  |  |  | 			pass | 
					
						
							|  |  |  | 		elif x not in b_list: | 
					
						
							|  |  |  | 			a_only.append(x, a_only_action) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			ax = os.path.join(a, x) | 
					
						
							|  |  |  | 			bx = os.path.join(b, x) | 
					
						
							|  |  |  | 			if os.path.isdir(ax) and os.path.isdir(bx): | 
					
						
							|  |  |  | 				if flags == '-r': | 
					
						
							|  |  |  | 					same = dircmp(ax, bx) | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					same = 0 | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				try: | 
					
						
							|  |  |  | 					same = cmp.cmp(ax, bx) | 
					
						
							|  |  |  | 				except (RuntimeError, os.error): | 
					
						
							|  |  |  | 					same = 0 | 
					
						
							|  |  |  | 			if same: | 
					
						
							|  |  |  | 				ab_same.append(x, ab_same_action) | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				ab_diff.append(x, ab_diff_action) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	for x in b_list: | 
					
						
							|  |  |  | 		if x in ['./', '../']: | 
					
						
							|  |  |  | 			pass | 
					
						
							|  |  |  | 		elif x not in a_list: | 
					
						
							|  |  |  | 			b_only.append(x, b_only_action) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	return data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Re-read the directory. | 
					
						
							|  |  |  | # Attempt to find the selected item back. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def update(w): | 
					
						
							|  |  |  | 	setbusy(w) | 
					
						
							|  |  |  | 	icol, irow = w.selection | 
					
						
							|  |  |  | 	if 0 <= icol < len(w.data) and 2 <= irow < len(w.data[icol]): | 
					
						
							|  |  |  | 		selname = w.data[icol][irow][0] | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		selname = '' | 
					
						
							|  |  |  | 	statcache.forget_dir(w.a) | 
					
						
							|  |  |  | 	statcache.forget_dir(w.b) | 
					
						
							|  |  |  | 	tablewin.select(w, (-1, -1)) | 
					
						
							|  |  |  | 	tablewin.update(w, diffdata(w.a, w.b, w.flags)) | 
					
						
							|  |  |  | 	if selname: | 
					
						
							|  |  |  | 		for icol in range(len(w.data)): | 
					
						
							|  |  |  | 			for irow in range(2, len(w.data[icol])): | 
					
						
							|  |  |  | 				if w.data[icol][irow][0] == selname: | 
					
						
							|  |  |  | 					tablewin.select(w, (icol, irow)) | 
					
						
							|  |  |  | 					break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Action functions for table items in directory diff windows | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def header_action(w, string, (icol, irow), (pos, clicks, button, mask)): | 
					
						
							|  |  |  | 	tablewin.select(w, (-1, -1)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def a_only_action(w, string, (icol, irow), (pos, clicks, button, mask)): | 
					
						
							|  |  |  | 	tablewin.select(w, (icol, irow)) | 
					
						
							|  |  |  | 	if clicks == 2: | 
					
						
							|  |  |  | 		w2 = anyopen(os.path.join(w.a, string)) | 
					
						
							|  |  |  | 		if w2: | 
					
						
							|  |  |  | 			w2.parent = w | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def b_only_action(w, string, (icol, irow), (pos, clicks, button, mask)): | 
					
						
							|  |  |  | 	tablewin.select(w, (icol, irow)) | 
					
						
							|  |  |  | 	if clicks == 2: | 
					
						
							|  |  |  | 		w2 = anyopen(os.path.join(w.b, string)) | 
					
						
							|  |  |  | 		if w2: | 
					
						
							|  |  |  | 			w2.parent = w | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ab_diff_action(w, string, (icol, irow), (pos, clicks, button, mask)): | 
					
						
							|  |  |  | 	tablewin.select(w, (icol, irow)) | 
					
						
							|  |  |  | 	if clicks == 2: | 
					
						
							|  |  |  | 		w2 = anydiff(os.path.join(w.a, string), os.path.join(w.b, string),'') | 
					
						
							|  |  |  | 		w2.parent = w | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ab_same_action(w, string, sel, detail): | 
					
						
							|  |  |  | 	ax = os.path.join(w.a, string) | 
					
						
							|  |  |  | 	if os.path.isdir(ax): | 
					
						
							|  |  |  | 		ab_diff_action(w, string, sel, detail) | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		a_only_action(w, string, sel, detail) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def anyopen(name): # Open any kind of document, ignore errors | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		w = anywin.open(name) | 
					
						
							|  |  |  | 	except (RuntimeError, os.error): | 
					
						
							|  |  |  | 		stdwin.message('Can\'t open ' + name) | 
					
						
							|  |  |  | 		return 0 | 
					
						
							|  |  |  | 	addstatmenu(w, [name]) | 
					
						
							|  |  |  | 	return w | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def dircmp(a, b): # Compare whether two directories are the same | 
					
						
							|  |  |  | 	# To make this as fast as possible, it uses the statcache | 
					
						
							|  |  |  | 	print '  dircmp', a, b | 
					
						
							|  |  |  | 	a_list = dircache.listdir(a) | 
					
						
							|  |  |  | 	b_list = dircache.listdir(b) | 
					
						
							|  |  |  | 	for x in a_list: | 
					
						
							|  |  |  | 		if skipthis(x): | 
					
						
							|  |  |  | 			pass | 
					
						
							|  |  |  | 		elif x not in b_list: | 
					
						
							|  |  |  | 			return 0 | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			ax = os.path.join(a, x) | 
					
						
							|  |  |  | 			bx = os.path.join(b, x) | 
					
						
							|  |  |  | 			if statcache.isdir(ax) and statcache.isdir(bx): | 
					
						
							|  |  |  | 				if not dircmp(ax, bx): return 0 | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				try: | 
					
						
							|  |  |  | 					if not cmpcache.cmp(ax, bx): return 0 | 
					
						
							|  |  |  | 				except (RuntimeError, os.error): | 
					
						
							|  |  |  | 					return 0 | 
					
						
							|  |  |  | 	for x in b_list: | 
					
						
							|  |  |  | 		if skipthis(x): | 
					
						
							|  |  |  | 			pass | 
					
						
							|  |  |  | 		elif x not in a_list: | 
					
						
							|  |  |  | 			return 0 | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # View menu (for dir diff windows only) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def addviewmenu(w): | 
					
						
							|  |  |  | 	w.viewmenu = m = w.menucreate('View') | 
					
						
							|  |  |  | 	m.action = [] | 
					
						
							|  |  |  | 	add(m, 'diff -r A B', diffr_ab) | 
					
						
							|  |  |  | 	add(m, 'diff A B', diff_ab) | 
					
						
							|  |  |  | 	add(m, 'diff -b A B', diffb_ab) | 
					
						
							|  |  |  | 	add(m, 'diff -c A B', diffc_ab) | 
					
						
							|  |  |  | 	add(m, 'gdiff A B', gdiff_ab) | 
					
						
							|  |  |  | 	add(m, ('Open A   ', 'A'), open_a) | 
					
						
							|  |  |  | 	add(m, ('Open B   ', 'B'), open_b) | 
					
						
							|  |  |  | 	add(m, 'Rescan', rescan) | 
					
						
							|  |  |  | 	add(m, 'Rescan -r', rescan_r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Action menu (for dir diff windows only) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def addactionmenu(w): | 
					
						
							|  |  |  | 	w.actionmenu = m = w.menucreate('Action') | 
					
						
							|  |  |  | 	m.action = [] | 
					
						
							|  |  |  | 	add(m, 'cp A B', cp_ab) | 
					
						
							|  |  |  | 	add(m, 'rm B', rm_b) | 
					
						
							|  |  |  | 	add(m, '', nop) | 
					
						
							|  |  |  | 	add(m, 'cp B A', cp_ba) | 
					
						
							|  |  |  | 	add(m, 'rm A', rm_a) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Main menu (global): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def mainmenu(): | 
					
						
							|  |  |  | 	m = stdwin.menucreate('Wdiff') | 
					
						
							|  |  |  | 	m.action = [] | 
					
						
							|  |  |  | 	add(m, ('Quit wdiff', 'Q'), quit_wdiff) | 
					
						
							|  |  |  | 	add(m, 'Close subwindows', close_subwindows) | 
					
						
							|  |  |  | 	return m | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def add(m, text, action): | 
					
						
							|  |  |  | 	m.additem(text) | 
					
						
							|  |  |  | 	m.action.append(action) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def quit_wdiff(w, m, item): | 
					
						
							|  |  |  | 	if askyesno('Really quit wdiff altogether?', 1): | 
					
						
							|  |  |  | 		sys.exit(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def close_subwindows(w, m, item): | 
					
						
							|  |  |  | 	while 1: | 
					
						
							|  |  |  | 		for w2 in gwin.windows: | 
					
						
							|  |  |  | 			if w2.parent == w: | 
					
						
							|  |  |  | 				close_subwindows(w2, m, item) | 
					
						
							|  |  |  | 				w2.close(w2) | 
					
						
							|  |  |  | 				break # inner loop, continue outer loop | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			break # outer loop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def diffr_ab(w, m, item): | 
					
						
							|  |  |  | 	dodiff(w, '-r') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def diff_ab(w, m, item): | 
					
						
							|  |  |  | 	dodiff(w, '') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def diffb_ab(w, m, item): | 
					
						
							|  |  |  | 	dodiff(w, '-b') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def diffc_ab(w, m, item): | 
					
						
							|  |  |  | 	dodiff(w, '-c') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def gdiff_ab(w, m, item): # Call SGI's gdiff utility | 
					
						
							|  |  |  | 	x = getselection(w) | 
					
						
							|  |  |  | 	if x: | 
					
						
							|  |  |  | 		a, b = os.path.join(w.a, x), os.path.join(w.b, x) | 
					
						
							|  |  |  | 		if os.path.isdir(a) or os.path.isdir(b): | 
					
						
							|  |  |  | 			stdwin.fleep() # This is for files only | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			diffcmd = 'gdiff' | 
					
						
							|  |  |  | 			diffcmd = diffcmd + mkarg(a) + mkarg(b) + ' &' | 
					
						
							|  |  |  | 			print diffcmd | 
					
						
							|  |  |  | 			sts = os.system(diffcmd) | 
					
						
							|  |  |  | 			if sts: print 'Exit status', sts | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def dodiff(w, flags): | 
					
						
							|  |  |  | 	x = getselection(w) | 
					
						
							|  |  |  | 	if x: | 
					
						
							|  |  |  | 		w2 = anydiff(os.path.join(w.a, x), os.path.join(w.b, x), flags) | 
					
						
							|  |  |  | 		w2.parent = w | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def open_a(w, m, item): | 
					
						
							|  |  |  | 	x = getselection(w) | 
					
						
							|  |  |  | 	if x: | 
					
						
							|  |  |  | 		w2 = anyopen(os.path.join(w.a, x)) | 
					
						
							|  |  |  | 		if w2: | 
					
						
							|  |  |  | 			w2.parent = w | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def open_b(w, m, item): | 
					
						
							|  |  |  | 	x = getselection(w) | 
					
						
							|  |  |  | 	if x: | 
					
						
							|  |  |  | 		w2 = anyopen(os.path.join(w.b, x)) | 
					
						
							|  |  |  | 		if w2: | 
					
						
							|  |  |  | 			w2.parent = w | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def rescan(w, m, item): | 
					
						
							|  |  |  | 	w.flags = '' | 
					
						
							|  |  |  | 	update(w) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def rescan_r(w, m, item): | 
					
						
							|  |  |  | 	w.flags = '-r' | 
					
						
							|  |  |  | 	update(w) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def rm_a(w, m, item): | 
					
						
							|  |  |  | 	x = getselection(w) | 
					
						
							|  |  |  | 	if x: | 
					
						
							|  |  |  | 		if x[-1:] == '/': x = x[:-1] | 
					
						
							|  |  |  | 		x = os.path.join(w.a, x) | 
					
						
							|  |  |  | 		if os.path.isdir(x): | 
					
						
							|  |  |  | 			if askyesno('Recursively remove A directory ' + x, 1): | 
					
						
							|  |  |  | 				runcmd('rm -rf' + mkarg(x)) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			runcmd('rm -f' + mkarg(x)) | 
					
						
							|  |  |  | 		update(w) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def rm_b(w, m, item): | 
					
						
							|  |  |  | 	x = getselection(w) | 
					
						
							|  |  |  | 	if x: | 
					
						
							|  |  |  | 		if x[-1:] == '/': x = x[:-1] | 
					
						
							|  |  |  | 		x = os.path.join(w.b, x) | 
					
						
							|  |  |  | 		if os.path.isdir(x): | 
					
						
							|  |  |  | 			if askyesno('Recursively remove B directory ' + x, 1): | 
					
						
							|  |  |  | 				runcmd('rm -rf' + mkarg(x)) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			runcmd('rm -f' + mkarg(x)) | 
					
						
							|  |  |  | 		update(w) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def cp_ab(w, m, item): | 
					
						
							|  |  |  | 	x = getselection(w) | 
					
						
							|  |  |  | 	if x: | 
					
						
							|  |  |  | 		if x[-1:] == '/': x = x[:-1] | 
					
						
							|  |  |  | 		ax = os.path.join(w.a, x) | 
					
						
							|  |  |  | 		bx = os.path.join(w.b, x) | 
					
						
							|  |  |  | 		if os.path.isdir(ax): | 
					
						
							|  |  |  | 			if os.path.exists(bx): | 
					
						
							|  |  |  | 				m = 'Can\'t copy directory to existing target' | 
					
						
							|  |  |  | 				stdwin.message(m) | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			runcmd('cp -r' + mkarg(ax) + mkarg(w.b)) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			runcmd('cp' + mkarg(ax) + mk2arg(w.b, x)) | 
					
						
							|  |  |  | 		update(w) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def cp_ba(w, m, item): | 
					
						
							|  |  |  | 	x = getselection(w) | 
					
						
							|  |  |  | 	if x: | 
					
						
							|  |  |  | 		if x[-1:] == '/': x = x[:-1] | 
					
						
							|  |  |  | 		ax = os.path.join(w.a, x) | 
					
						
							|  |  |  | 		bx = os.path.join(w.b, x) | 
					
						
							|  |  |  | 		if os.path.isdir(bx): | 
					
						
							|  |  |  | 			if os.path.exists(ax): | 
					
						
							|  |  |  | 				m = 'Can\'t copy directory to existing target' | 
					
						
							|  |  |  | 				stdwin.message(m) | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			runcmd('cp -r' + mkarg(bx) + mkarg(w.a)) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			runcmd('cp' + mk2arg(w.b, x) + mkarg(ax)) | 
					
						
							|  |  |  | 		update(w) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def nop(args): | 
					
						
							|  |  |  | 	pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def getselection(w): | 
					
						
							|  |  |  | 	icol, irow = w.selection | 
					
						
							|  |  |  | 	if 0 <= icol < len(w.data): | 
					
						
							|  |  |  | 		if 0 <= irow < len(w.data[icol]): | 
					
						
							|  |  |  | 			return w.data[icol][irow][0] | 
					
						
							|  |  |  | 	stdwin.message('no selection') | 
					
						
							|  |  |  | 	return '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def runcmd(cmd): | 
					
						
							|  |  |  | 	print cmd | 
					
						
							|  |  |  | 	sts, output = commands.getstatusoutput(cmd) | 
					
						
							|  |  |  | 	if sts or output: | 
					
						
							|  |  |  | 		if not output: | 
					
						
							|  |  |  | 			output = 'Exit status ' + `sts` | 
					
						
							|  |  |  | 		stdwin.message(output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Status menu (for all kinds of windows) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def addstatmenu(w, files): | 
					
						
							|  |  |  | 	w.statmenu = m = w.menucreate('Stat') | 
					
						
							|  |  |  | 	m.files = files | 
					
						
							|  |  |  | 	m.action = [] | 
					
						
							|  |  |  | 	for file in files: | 
					
						
							|  |  |  | 		m.additem(commands.getstatus(file)) | 
					
						
							|  |  |  | 		m.action.append(stataction) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def stataction(w, m, item): # Menu item action for stat menu | 
					
						
							|  |  |  | 	file = m.files[item] | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		m.setitem(item, commands.getstatus(file)) | 
					
						
							|  |  |  | 	except os.error: | 
					
						
							|  |  |  | 		stdwin.message('Can\'t get status for ' + file) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Compute a suitable window title from two paths | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def mktitle(a, b): | 
					
						
							|  |  |  | 	if a == b: return a | 
					
						
							|  |  |  | 	i = 1 | 
					
						
							|  |  |  | 	while a[-i:] == b[-i:]: i = i+1 | 
					
						
							|  |  |  | 	i = i-1 | 
					
						
							|  |  |  | 	if not i: | 
					
						
							|  |  |  | 		return a + '  ' + b | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		return '{' + a[:-i] + ',' + b[:-i] + '}' + a[-i:] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Ask a confirmation question | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def askyesno(prompt, default): | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		return stdwin.askync(prompt, default) | 
					
						
							|  |  |  | 	except KeyboardInterrupt: | 
					
						
							|  |  |  | 		return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Display a message "busy" in a window, and mark it for updating | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def setbusy(w): | 
					
						
							|  |  |  | 	left, top = w.getorigin() | 
					
						
							|  |  |  | 	width, height = w.getwinsize() | 
					
						
							|  |  |  | 	right, bottom = left + width, top + height | 
					
						
							|  |  |  | 	d = w.begindrawing() | 
					
						
							|  |  |  | 	d.erase((0, 0), (10000, 10000)) | 
					
						
							|  |  |  | 	text = 'Busy...' | 
					
						
							|  |  |  | 	textwidth = d.textwidth(text) | 
					
						
							|  |  |  | 	textheight = d.lineheight() | 
					
						
							|  |  |  | 	h, v = left + (width-textwidth)/2, top + (height-textheight)/2 | 
					
						
							|  |  |  | 	d.text((h, v), text) | 
					
						
							|  |  |  | 	del d | 
					
						
							|  |  |  | 	w.change((0, 0), (10000, 10000)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Main function | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def main(): | 
					
						
							|  |  |  | 	print 'wdiff: warning: this program does NOT make backups' | 
					
						
							|  |  |  | 	argv = sys.argv | 
					
						
							|  |  |  | 	flags = '' | 
					
						
							|  |  |  | 	if len(argv) >= 2 and argv[1][:1] == '-': | 
					
						
							|  |  |  | 		flags = argv[1] | 
					
						
							|  |  |  | 		del argv[1] | 
					
						
							| 
									
										
										
										
											1994-10-08 19:09:41 +00:00
										 |  |  | 	stdwin.setdefscrollbars(0, 1) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	m = mainmenu() # Create menu earlier than windows | 
					
						
							|  |  |  | 	if len(argv) == 2: # 1 argument | 
					
						
							|  |  |  | 		w = anyopen(argv[1]) | 
					
						
							|  |  |  | 		if not w: return | 
					
						
							|  |  |  | 	elif len(argv) == 3: # 2 arguments | 
					
						
							|  |  |  | 		w = anydiff(argv[1], argv[2], flags) | 
					
						
							|  |  |  | 		w.parent = () | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		sys.stdout = sys.stderr | 
					
						
							|  |  |  | 		print 'usage:', argv[0], '[diff-flags] dir-1 [dir-2]' | 
					
						
							|  |  |  | 		sys.exit(2) | 
					
						
							|  |  |  | 	del w # It's preserved in gwin.windows | 
					
						
							|  |  |  | 	while 1: | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			gwin.mainloop() | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		except KeyboardInterrupt: | 
					
						
							|  |  |  | 			pass	# Just continue... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Start the main function (this is a script) | 
					
						
							|  |  |  | main() |