代码拉取完成,页面将自动刷新
require 'strscan'
require 'yaml'
require 'set'
require_relative 'autoconf_condition_parser'
EXAMPLE_OUTPUT = <<YAML
depends:
$name:
type: lib|file|header|tool|prog
feature: # set if only valid for feature
required: true|false
on_var: k=v
set_var: [k=v]
features:
$name:
argv: --enable-xxx
help: some help string
default: true|false # if nil: no default
set_var: [k=v]
YAML
INVERT_VAL = {
'true' => 'false',
'false' => 'true',
'yes' => 'no',
'no' => 'yes',
'1' => '0',
'0' => '1',
}
VAL_TRUE = {
'true' => true,
'yes' => true,
'1' => true,
'false' => false,
'no' => false,
'0' => false,
}
class AutoconfDepends < AutoconfConditionParser
def initialize()
super()
# all quotes removed for compare
# ['var1=v1'] = 'var2=v2'
# ['var1=NON_EMPTY'] = 'var2=v2'
@infer_vars = {}
@ensure_vars = Set.new
@depends = {}
@features = {}
end
def run_all
puts "parse_macros"
parse_macros
save_macros
puts "parse_conditions"
parse_conditions
save_conditions
puts "build_depends"
build_depends
save_depends
end
def build_depends
@conditional_commands = YAML.load_file(File.join(@configure_ac_dir, "conditions.yaml")) if @conditional_commands.empty?
@macros = YAML.load_file(File.join(@configure_ac_dir, "macros.yaml")) if @macros.empty?
map_vars
add_features
add_depends
add_depends_on_var
add_inter_depends
end
def save_depends
h = {
'infer_vars' => @infer_vars,
'ensure_vars' => @ensure_vars.to_a,
'depends' => @depends,
'features' => @features,
}
fn = File.join(@configure_ac_dir, "depends.yaml")
File.write(fn, h.to_yaml)
end
def split_help_string(s)
if s =~ /\s*AS_HELP_STRING\(\s*\[(.*?)\]\s*,?\s*\[(.*)\]\s*\)\s*$/m
return $1, $2
else
argv, sep, help = s.partition /\s/
return argv, help
end
end
def add_features
@macros.each do |k, v|
case k
when /^AC_ARG_(ENABLE)/, /^AC_ARG_(WITH)/
kk = v['FEATURE']
h = {
'name' => kk,
'set_var' => ["#{$1.downcase}_#{kk.sub(/-/, '_')}=yes"],
}
h['argv'], h['help'] = split_help_string(v['HELP-STRING']) if v.include? 'HELP-STRING'
if v['ACTION-D'] =~ /([a-zA-Z_0-9]+=)['"]?(true|yes|1)/
h['default'] = true
h['set_var'].append($1 + $2) unless h['set_var'].include? ($1 + $2)
elsif v['ACTION-D'] =~ /([a-zA-Z_0-9]+=)['"]?(false|no|0)/
h['default'] = false
h['set_var'].append($1 + INVERT_VAL[$2]) unless h['set_var'].include? ($1 + INVERT_VAL[$2])
elsif v['ACTION-D'] =~ /([a-zA-Z_0-9]+=.*)/
h['set_var'].append($1)
elsif h['argv'] =~ /^--enable-/
h['default'] = false
elsif h['argv'] =~ /^--disable-/
h['default'] = true
end
@features[kk] = h
end
end
end
def get_macro_type(macro)
i = macro.chomp('_ONCE').chomp('_FEATURE_CHECK').rindex('_')
macro[i+1..-1].downcase.chomp('s')
end
def add_depend_action(k, v)
macro = k.sub(/\..*/m, '')
kk = AUTOCONF_MACRO_PARAMS[macro][0]
h = {
'type' => get_macro_type(macro),
'value' => v[kk],
}
if v['ACTION-F'] && v['ACTION-F'] =~ /([a-zA-Z_0-9]+=['"]?[a-zA-Z0-9-]+['"]?)/
h['set_var'] = [$1.delete('\'"')]
end
if v['ACTION-N'] && v['ACTION-N'] =~ /AC_MSG_FAILURE|AC_MSG_ERROR/
h['required'] = true
end
@depends[k] = h
end
def get_first_word(v)
a = v.split(/[^a-zA-Z0-9_-]/).reject { |s| s.empty? }
a.first
end
def add_depend_value(k, v)
macro = k.sub(/\..*/, '')
h = {
'type' => get_macro_type(macro),
'value' => (v['PROG'] || v['PROGS']),
}
# XXX: first or all?
if v['VALUE-F']
h['set_var'] = [ "#{v['VARIABLE']}=#{v['VALUE-F']}" ]
elsif v['PROG']
h['set_var'] = [ "#{v['VARIABLE']}=#{get_first_word(v['PROG'])}" ]
elsif v['PROGS']
h['set_var'] = [ "#{v['VARIABLE']}=#{get_first_word(v['PROGS'])}" ]
end
@depends[k] = h
end
def add_depends
@macros.each do |k, v|
case k
when /^AC_CHECK_HEADERS_ONCE/,
/^AC_CHECK_FILE/,
/^AC_CHECK_FILES/,
/^AC_CHECK_HEADER/,
/^AC_CHECK_HEADERS/,
/^AC_CHECK_LIB/,
/^AC_SEARCH_LIBS/,
/^PKG_CHECK_MODULES/
add_depend_action(k, v)
when /^AC_CHECK_PROGS/,
/^AC_CHECK_PROG/,
/^AC_CHECK_TARGET_TOOLS/,
/^AC_CHECK_TARGET_TOOL/,
/^AC_CHECK_TOOLS/,
/^AC_CHECK_TOOL/,
/^AC_PATH_PROGS_FEATURE_CHECK/,
/^AC_PATH_PROGS/,
/^AC_PATH_PROG/,
/^AC_PATH_TARGET_TOOL/,
/^AC_PATH_TOOL/
add_depend_value(k, v)
end
end
end
# - command: "AC_CHECK_LIB([udev], [main], ...
# conditions:
# - test "$with_udev" != "no"
# =>
# depends:
# AC_CHECK_LIB.udev:
# on_var: with_udev=yes
def add_depends_on_var
@conditional_commands.each do |item|
cmd = item['command']
cond = item['conditions']
next unless cond.size == 1
c0 = cond[0].delete('\'"')
if c0.index('||')
# remove the 2nd check in such case:
# if test "$with_gnutls" = "yes" || test "$with_gnutls" = ""; then
# PKG_CHECK_MODULES(GNUTLS, gnutls,
ca = c0.split(' || ').reject { |c| c =~ / = (auto)?$/ }
next unless ca.size == 1
c0 = ca[0]
end
next unless cmd =~ /(AC_CHECK_|AC_PATH_|AC_SEARCH_LIBS|PKG_CHECK_MODULES)(.*?)\(\s*\[?(.*?)\]?[,)]/m
k = $1 + $2 + '.' + $3.strip
next unless @depends.include? k
if c0 =~ /([a-zA-Z_0-9]+) != (true|false|yes|no|0|1)/
c0 = $1 + ' = ' + INVERT_VAL[$2]
end
@depends[k]['on_var'] = reduce_test_kv(c0)
end
end
def add_inter_depends
@features.each do |feat, ff|
ff['set_var'].each do |feat_var|
@depends.each do |dep, dd|
if dd['on_var'] == feat_var
dd['feature'] = feat
end
Array(dd['set_var']).each do |dep_var|
if dep_var == @infer_vars[feat_var]
dd['feature'] = feat
dd['required'] = true
end
end
end
end
end
end
def reduce_var(v)
v.delete(' \'"${}')
end
def reduce_val(v)
v.delete(' \'"')
end
# convert test form to assign form
def reduce_test_kv(test)
test.sub!(/^test /, '')
if test =~ / = /
var, val = test.split(' = ')
op = '='
else
var, val = test.split(' != ')
op = '!='
end
return reduce_var(var) + op + reduce_val(val || '')
end
def map_var_pair(test1, test2)
return unless test2
kv1 = reduce_test_kv(test1)
kv2 = reduce_test_kv(test2)
return if kv1 =~ /[^-=.a-zA-Z_0-9]/
return if kv2 =~ /[^-=.a-zA-Z_0-9]/
if kv1 =~ /^enable_|^with_/ ## kv2 is typically have_xxx or XXX_LIBS
@infer_vars[kv1] = kv2
else
@infer_vars[kv2] = kv1
end
end
def invert_test(test)
case test
when / != /
test.sub(/!=/, '=')
when / = ""/, / = ''/
test.sub(/= ""/, '= NON_EMPTY')
when / = ['"]?(no|false|0)['"]?$/
test.sub(/= .*/, "= #{INVERT_VAL[$1]}")
else
debug "WARNING: failed to invert test '#{test}'"
nil
end
end
def map_vars
@conditional_commands.each do |item|
cmd = item['command']
cond = item['conditions']
if cmd =~ /^(AC_MSG_FAILURE|AC_MSG_ERROR)/
if cond.size == 1
next unless cond[0].index('=')
next unless itest = invert_test(cond[0])
@ensure_vars.add reduce_test_kv(itest)
elsif cond.size == 2
if cond[0] =~ / = /
map_var_pair(cond[0], invert_test(cond[1]))
elsif cond[1] =~ / = /
map_var_pair(cond[1], invert_test(cond[0]))
end
end
end
end
end
end
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。