This is the builtin Lua option definitions code as included in FA 0.11. You can find actual version of this code by running fa --print-config
.
AddOptions{
{'min_size', '-smBYTES --min-size=BYTES --SizeMore=BYTES', 'minimum filesize to process',
OPTION_BYTES, function(min_size) AddFileFilter('size>='..min_size) end},
{'max_size', '-slBYTES --max-size=BYTES --SizeLess=BYTES', 'maximum filesize to process',
OPTION_BYTES, function(max_size) AddFileFilter('size<='..max_size) end},
{'select_archive_bit', '-ao --select-archive-bit --SelectArchiveBit', "select only files with Archive bit set",
OPTION_BOOL, function() AddFileFilter('btest(attr,0x20)') end},
}
AddOption('include', '-nFILESPECS --include=FILESPECS', 'include only files matching FILESPECS',
OPTION_LIST,
function(filespecs)
local filters = table.map (filespecs, function(filespec) return string.format('string_match(name,%q)', wildcard2pattern(filespec)) end)
AddFileFilter( '('..table.concat(filters,') or (')..')' )
end)
AddOption('exclude', '-xFILESPECS --exclude=FILESPECS', 'exclude FILESPECS from operation',
OPTION_LIST,
function(filespecs)
for _,filespec in ipairs(filespecs) do
AddFileFilter( string.format('not string_match(name,%q)', wildcard2pattern(filespec)) )
end
end)
AddOption('filter', '-fEXPR --filter=EXPR', 'filter files by Lua expression employing vars name, type, size, time and attr',
OPTION_LIST,
function(filters)
for _,filter in ipairs(filters) do
if not string.match (' '..filter..' ', '[^%w_]return[^%w_]') then
AddFileFilter(filter)
else
onFileFilter('function (name, type, size, time, attr); '..filter..'; end')
end
end
end)
AddOption('autogenerate', '-ag[FORMAT] --autogenerate=[FORMAT]', 'append to archive name string generated by strftime(FORMAT||"%Y%m%d%H%M%S")',
OPTION_STRING,
function(format)
if format~='-' and format~='--' then
local timestr = os.date(format=='' and '%Y%m%d%H%M%S' or format)
command.arcname = command.arcname .. timestr
end
end)
AddOption('crc_only', '--crc-only --crconly', "save/check CRC, but don't store data",
OPTION_BOOL,
function()
command.compression_groups = {""}
command.compression_methods = {CRC_ONLY_COMPRESSION}
end)
AddOption('large_page_mode', '-slpMODE', 'set large page mode (TRY(default), FORCE(+), DISABLE(-), MALLOC)',
OPTION_STRING,
function(mode)
if mode=='' then mode = 'TRY' end
if mode=='-' then mode = 'DISABLE' end
if mode=='+' then mode = 'FORCE' end
SetLargePageMode(mode)
end)
AddOption('prefetch', '--prefetch[PARAMS]', 'prefetching to the OS file cache (:1g:8 means read 1GB ahead using 8 threads)',
OPTION_STRING,
function(params)
if params=='' then params = '2g:8' end
if params=='-' then params = '0' end
for word in params:gmatch('([^:=/,;]+)') do
local n = parse_num(word)
if n then
command.prefetch_threads = n
else
local size = parse_mem(word,'b')
if size then
command.prefetch_cache = size
else
return 'cannot parse "'..word..'" as number of threads or cache size'
end
end
end
end)
--[[ **********************************************************************************************************************************
*** 'Method change (-mc)' option implementation****************************************************************************************
*************************************************************************************************************************************]]
AddOption('method_change', '-mcDIRECTIVE', 'modify compressor: [$group1,$group2][:]-$group,-algo,+algo,algo1/algo2',
-- Parsing function
function(param)
local action
--mcd-: replace rar-compatible abbreviated directives with longer explicit ones
local rarAbbrevs = {d="-delta", e="-exe", l="-lzp", r="-rep", z="-dict", a="-$wav", c="-$bmp", t="-$text"}
param = rarAbbrevs[param:match('^(%a)%-$')] or param
-- Split param into list of groups and operation to perform on these groups
local groups,operation = param:match('^:?($.-)([:+-].+)$')
if not groups then
groups = ''
operation = param
end
--mc:lzma/lzma:max:512mb
local old_compressor,new_compressor = operation:match('^:?(.+)/([^$].*)$')
if old_compressor then action = function(env) env.replace_compressor(groups,old_compressor,DecodeMethod(new_compressor)) end else
--mc+precomp+xtor
local new_compressor = operation:match('^:?%+(.+)$') or operation:match('^:?(.+)%+$')
if new_compressor then action = function(env) env.add_compressor(groups,DecodeMethod(new_compressor)) end else
--mc-$wav,$bmp
local old_groups = operation:match('^:?%-($.+)$') or operation:match('^:?($.+)%-$')
if old_groups and (groups=='') then action = function(env) env.remove_groups(old_groups) end else
--mc-rep,lzp
local old_compressor = operation:match('^:?%-(.+)$') or operation:match('^:?(.+)%-$')
if old_compressor then action = function(env) env.remove_compressor(groups,old_compressor) end else
--unrecognized
return 'Bad option format'
end end end end
optvalue.method_change = optvalue.method_change or {}
table.insert (optvalue.method_change, action)
end,
-- Post-processing function
function()
local cgroups, cmethods = command.compression_groups, command.compression_methods
cgroups[1] = '$default'
-- Filter cmethods[i] through f if cgroup[i] is in the `groups` list or the list is empty
local function filter_methods (groups, f)
for i,group in ipairs(cgroups) do
if groups=="" or group:in_list(groups) then
cmethods[i] = f(cmethods[i],group)
end
end
end
-- Filter through the f each compressor in the `groups`
local function filter_compressors (groups, f)
filter_methods (groups, function (method)
local cm = {}
for old_compressor in string.gmatch(method, "[^+]+") do
local name = string.match (old_compressor..':', '^([^:]*):')
local new_compressor = f(name,old_compressor)
if new_compressor ~= "" then
table.insert(cm, new_compressor or old_compressor)
end
end
return table.concat(cm,'+')
end)
end
local env = {}
function env.add_compressor(groups,compressor)
filter_methods (groups, function(method) return compressor..'+'..method; end)
end
function env.replace_compressor(groups,old_names,new_compressor)
filter_compressors (groups, function(name) if name:in_list(old_names) then return new_compressor end end)
end
function env.remove_compressor(groups,names)
--mc-grzip removes groups like $bmp=mm+grzip where "grzip" is the last compressor in the chain
filter_methods (groups, function(method,group)
local compressors = split_method(method)
if #compressors>0 and group~='$default' then
local last_compressor_name = get_compressor_name(compressors[#compressors])
if last_compressor_name:in_list(names) then
compressors = {}
end
end
return join_method(compressors)
end)
--mc-grzip also removes grzip from middle of compression chain
filter_compressors (groups, function(name) if name:in_list(names) then return "" end end)
end
function env.remove_groups(groups)
filter_methods (groups, function() return "" end)
end
-- Modify the compressor by executing code built at the parsing stage
for _,directive in ipairs(optvalue.method_change or {}) do
directive(env)
end
-- Remove groups whose compression method became empty
local g,m = {},{}
cgroups[1] = ''
for i,method in ipairs(cmethods) do
if method > "" then
table.insert (g, cgroups[i])
table.insert (m, cmethods[i])
end
end
command.compression_groups, command.compression_methods = g,m
end)