Monday, November 08, 2010 at 12:06 AM.
system.verbs.builtins.table.compareContents
on compareContents (adr1, adr2, flDateSensitive=false, flCompareOutlinesAsOpml=false, flCompareMenubarScripts=false) {
<<Changes
<<12/2/02; 3:50:07 PM by JES
<<Add menubar and menubar script comparison.
<<11/29/02; 3:11:42 PM by JES
<<Created. Compare the contents of two tables. Return true if the contents are identical or false if not.
<<If flDateSensitive is true, then the creation and modification dates of non-scalars will be compared, including the create/modification date of the tables themselves.
<<If flCompareOutlinesAsOpml is true, then outline objects will be converted to OPML for comparison so that node attributes will be compared as well as heading text.
on visit (adr1, adr2) {
if flDateSensitive {
if timeModified (adr1) != timeModified (adr2) {
return (false)};
if timeCreated (adr1) != timeCreated (adr2) {
return (false)}};
if sizeOf (adr1^) != sizeOf (adr2^) {
return (false)};
local (adr);
for adr in adr1 {
local (name = nameOf (adr^));
local (adrdest = @adr2^.[name]);
if not defined (adrdest^) {
return (false)};
if typeOf (adr^) != typeOf (adrdest^) {
return (false)};
if flDateSensitive {
case typeOf (adr^) { //check create/mod dates on window objects
wptexttype;
outlinetype;
scripttype {
if timeModified (adr1) != timeModified (adr2) {
return (false)};
if timeCreated (adr1) != timeCreated (adr2) {
return (false)}}}};
case typeOf (adr^) {
tableType { //recurse
if not visit (adr, adrdest) {
return (false)}};
addresstype; //convert to strings to aviod errors for undefined addresses
wptexttype {
if string (adr^) != string (adrdest^) {
return (false)}};
scripttype;
outlinetype {
local (o1, o2);
if flCompareOutlinesAsOpml {
o1 = op.outlineToXml (adr);
o2 = op.outlineToXml (adrdest);
o1 = string.delete (o1, 1, string.patternMatch ("<body>", o1) - 1);
o2 = string.delete (o2, 1, string.patternMatch ("<body>", o2) - 1)}
else { //compare as strings
o1 = string (adr^);
o2 = string (adrdest^)};
if o1 != o2 {
reutrn (false)}};
binarytype {
if string (adr^) != string (adrdest^) {
return (false)};
if getBinaryType (adr) != getBinaryType (adrdest) {
return (false)}};
menubartype {
if string (adr^) != string (adrdest^) {
return (false)};
if flCompareMenubarScripts {
local (m1 = adr^, m2 = adrdest^);
local (oldtarget = target.set (@m1));
bundle { //expand the menus
op.firstSummit ();
op.fullExpand ();
target.set (@m2);
op.firstSummit ();
op.fullExpand ()};
on visit () {
loop {
target.set (@m1);
if op.countSubs (1) { //sub-menu
op.go (right, 1);
target.set (@m2);
op.go (right, 1);
if not visit () {
return (false)};
op.go (left, 1)}
else { //menu command
local (s1, s2, k1, k2);
menu.getScript (@s1);
k1 = menu.getCommandKey ();
target.set (@m2);
menu.getScript (@s2);
k2 = menu.getCommandKey ();
if string (s1) != string (s2) {
return (false)};
if k1 != k2 {
return (false)}};
if not op.go (down, 1) {
return (true)};
target.set (@m1);
op.go (down, 1)}};
if not visit () {
try {target.set (oldtarget)};
return (false)};
try {target.set (oldtarget)}}}}
else { //all other scalars and lists
if adr^ != adrdest^ {
return (false)}}};
return (true)};
return (visit (adr1, adr2))}
<<bundle //test code
<<table.compareContents (@scratchpad, @scratchpad)
<<true
<<table.compareContents (@scratchpad, @workspace)
<<false
<<table.compareContents (@user.bookmarksMenu, @user.bookmarksMenu, flCompareMenubarScripts:true)
<<true
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.