Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
-- (find-es "lua" "apt-move.lua")
-- (find-angg "LUA/inc.lua")
dofile(getenv("HOME").."/LUA/inc.lua")

-- «.read_and_split»	(to "read_and_split")
-- «.P_apply»		(to "P_apply")
-- «.foundlocaldeb»	(to "foundlocaldeb")
-- «.feeding_debs»	(to "feeding_debs")
-- «.debversions»	(to "debversions")



--#####
--#
--# Functions for reading deb lines from files and splitting them
--#
--#####
-- «read_and_split»  (to ".read_and_split")

function for_each_line(fname, func)
  local file, line
  file = openfile(fname, "r")
  while 1 do
    line = read(file)
    if not line then
      closefile(file)
      return
    end
    func(line)
  end
end

-- (find-fline "~/tmp/lua-manual.txt" "%")

function for_each_split_line(fname, splchar, func)
  for_each_line(fname,
    function (line)
      call(%func, split1(line, %splchar))
    end)
end

function for_each_stemv_line(fname, func)
  for_each_line(fname,
    function (line)
      local stem, version = stem_and_version(line)
      %func(stem, version, line)
    end)
end

-- px(stem_and_version("/var/cache/apt/archives/gcc_1%3a2.95.2-12_i386.deb"))
--   ==> "gcc"   "2.95.2-12"
--
function stem_and_version(s)
  local a = split1(s, "/")
  s = a[a.n]
  if strsub(s, -4) == ".deb" then s = strsub(s, 1, -5) end
  a = split1(s, "_")
  if strsub(a[2], 2, 4) == "%3a" then a[2] = strsub(a[2], 5) end
  return a[1], a[2]
end




stems = {}
installed = {}




--#####
--#
--# Functions to iterate over the debs in the array "installed"
--#
--#####
-- A basic building block: "for_each_stem"
-- (find-fline "~/tmp/lua-manual.txt" "for index, value in exp do block end")
-- (find-fline "~/tmp/lua-manual.txt" "foreachi")
function for_each_stem(f)
  local stem
  for i=1,getn(stems) do
    f(stems[i], installed[stems[i]])
  end
end

--#####
--#
--# Best way to iterate to produce output: P_apply("cond", "fargs", f)
--#
--#####
-- «P_apply»  (to ".P_apply")
-- (find-es "lua" "apt-move.lua_P_apply")
-- Args:
--   i - an entire installed[] structure, e.g. installed["gcc"]
--   s - a stem, e.g. "gcc"
--   v - a version, without epoch; e.g. "0.9.5d-2"
--   p - a path (from a "find");
--       e.g. "/var/cache/apt/archives/arena_1%3a0.3.62-1.1_i386.deb"
--   op - an official path taken from a "Packages" file,
--        e.g. "dists/potato/main/binary-i386/admin/eql_1.2-1.deb"
-- Conditions:
--   RV - right version deb
--   WV - wrong version deb
--   ND - no deb
--   OP - has an "official path"
--
function i_to_rv(i) return i.methods[1] == "RIGHTVERSIONDEB"; end
function i_to_wv(i) return i.methods[1] == "WRONGVERSIONDEB"; end
function i_to_nd(i) return i.methods[1] == "NODEB"; end
function i_to_has_op(i) return i.officialfname; end
--
conditions = {
  ["RV"] = function (s, i) return i_to_rv(i); end,
  ["WV"] = function (s, i) return i_to_wv(i); end,
  ["ND"] = function (s, i) return i_to_nd(i); end,
  ["RV&OP"] = function (s, i) return i_to_rv(i) and i_to_has_op(i); end,
  ["RV&~OP"] = function (s, i) return i_to_rv(i) and not i_to_has_op(i); end,
}
fargsfunctions = {
  ["s,i"] = function (s, i) return s, i; end,
  ["s,p,op"] = function (s, i) return s, i.path, i.officialfname; end,
  ["s,p"] = function (s, i) return s, i.path; end,
  ["s,v"] = function (s, i) return s, i.version; end,
  ["s"] = function (s, i) return s; end,
}
--
function P_apply(condstr, fargsstr, f)
  condition = conditions[condstr]
  fargsfunction = fargsfunctions[fargsstr]
  if not condition     then print("Bad condstr:", condstr) end
  if not fargsfunction then print("Bad fargsstr:", fargsstr) end
  for_each_stem(
    function (s, i)
      if %condition(s, i) then %f(%fargsfunction(s, i)) end
    end)
end




--#####
--#
--# Methods and method tables (for registering debs)
--#
--#####

-- «foundlocaldeb»  (to ".foundlocaldeb")
-- Our method tables start with only _[1]="class name".
NODEB           = {"NODEB"}
WRONGVERSIONDEB = {"WRONGVERSIONDEB"}
RIGHTVERSIONDEB = {"RIGHTVERSIONDEB"}

function NODEB.foundlocaldeb(i_stem, stem, version, path)
  tinsert(stems, stem)
  if i_stem.version == version then
    i_stem.methods = RIGHTVERSIONDEB
    i_stem.path = path
  else
    i_stem.methods = WRONGVERSIONDEB
    i_stem.badversions = {[version]=path}
  end
end
function WRONGVERSIONDEB.foundlocaldeb(i_stem, stem, version, path)
  if i_stem.version == version then
    i_stem.methods = RIGHTVERSIONDEB
    i_stem.path = path
  else
    -- keep only the last path to a certain bad-version deb
    i_stem.badversions[version] = path
  end
end
function RIGHTVERSIONDEB.foundlocaldeb(i_stem, stem, version, path)
end

  



--#####
--#
--# Functions to take deb names from various sources and feed them
--# into the "installed" array in different ways
--#
--#####

-- «feeding_debs»  (to ".feeding_debs")
-- Process the list of installed debs.
-- (find-angg ".zshrc" "installeddebs")
function Installed(fname)
  for_each_stemv_line(fname,
    function (stem, version, line)
      if not installed[stem] then
        installed[stem] = {methods=NODEB, version=version}
	tinsert(stems, stem)
      end
    end)
end

-- Process a list of debs obtained with "find".
function Found(fname)
  for_each_stemv_line(fname,
    function (stem, version, path)
      i_stem = installed[stem]
      if i_stem then
        i_stem.methods.foundlocaldeb(i_stem, stem, version, path)
      end
    end)
end

-- Process a listing of deb paths extracted from a "Packages" file
-- (find-angg ".zshrc" "pfilenames")
function Pfilenames(fname)
  for_each_stemv_line(fname,
    function (stem, version, path)
      i_stem = installed[stem]
      if i_stem then	-- only for installed packages
	-- keep only the first official path.
        i_stem.officialfname = i_stem.officialfname or path
      end
    end)
end




--#####
--#
--# Functions to compare versions of .debs
--# 2001jun13
--#
--#####

-- «debversions»  (to ".debversions")
-- (find-es "dpkg" "dpkg:debversions")
-- (defun find-pmt (str) (find-fline (ee-packfile "packaging.text.gz") str))
-- (find-pmt "5. Version numbering")
-- (find-pmt "<debian-revision>\n")
-- (find-pmt "compared lexically")
-- (find-pmt "--compare-versions")
-- (find-node "(lua)Patterns")

-- The <upstream-version> may contain only alphanumerics and the
-- characters `.' `+' `-' `:' (full stop, plus, hyphen, colon) and should
-- start with a digit. If there is no <debian-revision> then hyphens are
-- not allowed; if there is no <epoch> then colons are not allowed.

-- (find-fline "/var/cache/apt/archives/")
-- (find-luafile "README.rttpatch")

debv_epoch_re = regex("^(([0-9]+)(:|%3a))?(.*)")
debv_revision_re = regex("^([0-9][-A-Za-z0-9+.:]*)(-)([A-Za-z0-9+.]+)$")
debv_revisionless_re = regex("^([0-9][A-Za-z0-9+.:]*)$")

function parse_debversion(str)
  local p1, p2, a = match(str, debv_epoch_re)
  -- debv_epoch_re always succeeds
  local epoch, epochsep, rest = a[2], a[3], a[4]
  if not epoch then
    epoch, epochsep = 0, ""
  else
    epoch = tonumber(epoch)
  end
  p1, p2, a = match(rest, debv_revision_re)
  if p1 then
    local upversion, revisionsep, revision = a[1], a[2], a[3]
    return epoch, epochsep, upversion, revisionsep, revision
  end
  p1, p2, a = match(rest, debv_revisionless_re)
  if p1 then
    return epoch, epochsep, rest, "", ""
  end
  return nil, nil, nil, nil, nil, "Bad debversion: \""..str.."\""
  -- not checking: "if there is no <epoch> then colons are not allowed."
end

function debv_compare_nondigits(str1, str2)
  if str1 == str2 then
    return "="
  end
  local plus128 = function (c)
    return format("%c", strbyte(c)+128)
  end
  str1 = gsub(str1, "([^A-Za-z])", plus128)
  str2 = gsub(str2, "([^A-Za-z])", plus128)
  if str1 < str2 then
    return "older"
  else
    return "newer"
  end
end

function debv_compare_halfversions(str1, str2)
  while 1 do
    if str1 == str2 then return "=" end
    _, _, nondig1, dig1, str1 = strfind(str1, "^([^0-9]*)([0-9]*)(.*)$")
    _, _, nondig2, dig2, str2 = strfind(str2, "^([^0-9]*)([0-9]*)(.*)$")
    if not nondig1 == nondig2 then
      return nondig1 < nondig2 and "older" or "newer"
    end
    dig1 = tonumber(dig1) or 0
    dig2 = tonumber(dig2) or 0
    if not dig1 == dig2 then
      return nondig1 < nondig2 and "older" or "newer"
    end
  end
end

function debv_compare_versions(str1, str2)
  if str1 == str2 then return "=" end
  local epoch1, upversion1, debrevversion1, _
  local epoch2, upversion2, debrevversion2, rslt
  epoch1, _, upversion1, _, debrevversion1 = parse_debversion(str1)
  epoch2, _, upversion2, _, debrevversion2 = parse_debversion(str2)
  if epoch1 ~= epoch2 then
    return epoch1 < epoch2 and "older" or "newer"
  end
  rslt = debv_compare_halfversions(upversion1, upversion2)
  if rslt ~= "=" then return rslt end
  return debv_compare_halfversions(debrevversion1, debrevversion2)
end





-- Installed(arg[1])
-- Pfilenames(arg[2])
-- Found(arg[3])
-- p(installed)

-- (find-es "lua" "apt-move.lua")
-- (find-es "lua" "apt-move.lua_prep")
-- (find-es "lua" "apt-move.lua_P_apply")

comment = [[
# (find-angg ".zshrc" "debbasename")
#*
# «apt-move.lua_prep»  (to ".apt-move.lua_prep")
# (find-angg ".zshrc" "installeddebs")
installeddebs | sort \
  > /tmp/idebs

cat $SDEBIAN/dists/potato/main/binary-i386/Packages     | pfilenames \
  > /tmp/pdebs-main
cat $SDEBIAN/dists/potato/contrib/binary-i386/Packages  | pfilenames \
  > /tmp/pdebs-contrib
cat $SDEBIAN/dists/potato/non-free/binary-i386/Packages | pfilenames \
  > /tmp/pdebs-non-free

cat /tmp/pdebs-{main,contrib,non-free} > /tmp/pdebs

find /hdd6/debian/		-name '*.deb' | sort > /tmp/fdebs-CB
find $SDEBIAN/dists/potato	-name '*.deb' | sort > /tmp/fdebs-S
find /var/cache/apt/archives/	-name '*.deb' | sort > /tmp/fdebs-c

cat /tmp/fdebs-{CB,S,c} > /tmp/fdebs

# (find-fline "/tmp/")
# (find-fline "/tmp/idebs")
# (find-fline "/tmp/pdebs")
# (find-fline "/tmp/fdebs")
# (find-fline "$SDEBIAN/")
# (find-fline "/var/state/apt/lists/")

#*
# «apt-move.lua_P_apply»  (to ".apt-move.lua_P_apply")
# (find-angg "LUA/apt-move.lua" "P_apply")
# The preparation stage that produces the /tmp/?debs files is above.
lua ~/LUA/apt-move.lua -e '
  Installed ("/tmp/idebs")
  Pfilenames("/tmp/pdebs")
  Found     ("/tmp/fdebs")

  P_apply("RV&OP", "s,p,op", function (s, p, op)
      write(format("mv -iv %s %s\n", p, op))
    end)
  print()
  P_apply("RV&~OP", "s,p", function (s, p)
      write(format("# No official path: %s %s\n", s, p))
    end)
  print()
  P_apply("WV", "s,v", function (s, v)
      write(format("# No deb of the right version: %s_%s\n", s, v))
    end)
  print()
  P_apply("ND", "s,v", function (s, v)
      write(format("# No deb at all: %s_%s\n", s, v))
    end)

' |& tee ~/o
# (find-fline "~/o")
# (progn (find-fline "~/o") (wrap 0))
#*
cd ~/LUA/
a2ps -=p2iso apt-move.lua
make -f ~/LATEX/Makefile /tmp/o.p01
gv /tmp/o.ps &
#*
]]



--  Local Variables:
--  coding:               no-conversion
--  ee-anchor-format:     "«%s»"
--  ee-charset-indicator: "Ñ"
--  End: