1#!/usr/bin/env lua 2 3--[[ 4Takes two mandatory and one optiona argument 5* a file containing a dump of the old API 6* a file containing a dump of the new API 7* optionally "true" or "nodes" 8 true : show differences 9 nodes : also dump the content of added nodes 10 11This script will compare the two API and report any differences it sees 12optionally printing details of the difference 13 14Use this to quickly assess what has changed between two versions of DT 15 16Note that dumps are obtained via lua_doc/dumper.lua 17]] 18 19table = require "table" 20args = {...} 21oldapi = require(string.sub(args[1],1,-5)) 22newapi = require(string.sub(args[2],1,-5)) 23verbose = args[3] 24 25 26local function sorted_pairs (t, f) 27 local a = {} 28 for n in pairs(t) do table.insert(a, n) end 29 table.sort(a, f) 30 local i = 0 -- iterator variable 31 local iter = function () -- iterator function 32 i = i + 1 33 if a[i] == nil then return nil 34 else return a[i], t[a[i]] 35 end 36 end 37 return iter 38end 39 40local function length(ptree) 41 if #ptree == 0 then return 0 end 42 return length(ptree[2])+1 43end 44 45 46function find_parent(node,ptree) 47 if type(node) ~= "table" then return end 48 49 if length(ptree) == 0 then 50 node.__parent = {} 51 for k,v in sorted_pairs(node) do 52 find_parent(v,{k,node.__parent}) 53 end 54 return 55 end 56 57 if ptree[1] == "__parent" then return end 58 59 if not node.__parent or length(node.__parent) > length(ptree) then 60 node.__parent = ptree 61 for k,v in sorted_pairs(node) do 62 find_parent(v,{k,ptree}) 63 end 64 end 65end 66 67 68 69local function build_name(ptree) 70 if #ptree == 0 then return "" end 71 if #ptree[2] == 0 then return ptree[1] end 72 return build_name(ptree[2]).."."..ptree[1] 73end 74 75 76local function specific_filter(old,new,name,ptree) 77 if ptree[1] == "read" and ptree[2][1] == "__attributes" then 78 return true 79 end 80 if ptree[1] == "write" and ptree[2][1] == "__attributes" then 81 return true 82 end 83 if ptree[1] == "is_attribute" and ptree[2][1] == "__attributes" then 84 return true 85 end 86 if ptree[1] == "is_self" and ptree[2][1] == "__attributes" then 87 return true 88 end 89 if ptree[1] == "parent" and ptree[2][1] == "__attributes" then 90 return true 91 end 92 return false 93end 94 95 96local known = {} 97function dump_node(node,prefix) 98 if type(node) ~= "table" then 99 return tostring(node) 100 elseif known[node] then 101 return build_name(node.__parent) 102 elseif verbose== "nodes" then 103 known[node] = true 104 local result="{\n" 105 for k,v in sorted_pairs(node) do 106 if k ~= "__parent" and k ~="__done" then 107 result = result..prefix.." "..k.." = "..dump_node(v,prefix.." ").."\n" 108 end 109 end 110 result = result ..prefix.."}" 111 return result 112 else 113 return build_name(node.__parent) 114 end 115end 116 117function trace_change(name,change_type,old,new) 118 print(name.." : "..change_type) 119 if verbose then 120 print("**************** old ************************") 121 known = {} 122 print(dump_node(old,"")) 123 print("**************** new ************************") 124 known = {} 125 print(dump_node(new,"")) 126 print("*********************************************") 127 end 128end 129 130local function compare_any(old,new,ptree) 131 local name 132 if ptree[1] == "__done" then return end 133 if ptree[1] == "__parent" then return end 134 if type(old) == "table" and old.__done then return end 135 if type(old) == "table" then 136 name = build_name(old.__parent) 137 old.__done = true; 138 else 139 name = build_name(ptree) 140 end 141 if specific_filter(old,new,name,ptree) then 142 return 143 end 144 if old == nil then 145 trace_change(name,"Node added",old,new) 146 return 147 end 148 if new == nil then 149 trace_change(name,"Node deleted",old,new) 150 return 151 end 152 if type(old) ~= type(new) then 153 trace_change(name,"Type changed from "..type(old).." to "..type(new),old,new) 154 return 155 end 156 if type(old) ~= "table" then 157 if old ~= new then 158 trace_change(name,"("..type(old)..") value changed",old,new) 159 end 160 return 161 else 162 for k,v in sorted_pairs(old) do 163 compare_any(v,new[k],{k,old.__parent}) 164 end 165 for k,v in sorted_pairs(new) do 166 if not old[k] then 167 compare_any(old[k],v,{k,new.__parent}) 168 end 169 end 170 end 171 172end 173 174 175 176find_parent(oldapi,{}) 177find_parent(newapi,{}) 178 179compare_any(oldapi,newapi,{}) 180 181-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua 182