class Object
Public Instance Methods
aargh(message, exit_code = nil)
click to toggle source
# File bin/specificjson, line 2114 def aargh(message, exit_code = nil) $stderr.puts message exit exit_code unless exit_code.nil? end
all_requirements(piece, reqs)
click to toggle source
# File bin/specificjson, line 2334 def all_requirements(piece, reqs) unless reqs.include? piece['name'] reqs.push piece['name'] piece['requires'].each do |r| all_requirements($PIECES[r], reqs) unless reqs.include? r end end reqs end
arrange_needed(needed)
click to toggle source
# File bin/specificjson, line 2456 def arrange_needed(needed) pools = needed.select { |name| $pools.include? name } others = needed.reject { |name| pools.include?(name) } others.sort! { |a, b| compare_pieces(a, b) } last = others.rindex { |name| $pooled.include? name } needed = others.slice!(0, last + 1) others.concat pools others.sort! { |a, b| compare_pieces(a, b) } needed.concat others needed end
check_given(spec, kind, field, error)
click to toggle source
# File bin/specificjson, line 2159 def check_given(spec, kind, field, error) aargh(error, 4) unless spec[field] != $DEFAULT[kind][field] end
classify_expression(expr)
click to toggle source
# File bin/specificjson, line 2647 def classify_expression(expr) # Simple but good enough for now. If expression gets confused with method, # add space in any place where it does not affect the meaning. return :expression if expr.nil? # Will go unused in this case. return :expression if expr.include? ' ' return :expression if expr.include?('.') || expr.include?('->') return :method if expr.end_with? '()' :member end
compare_pieces(a, b)
click to toggle source
# File bin/specificjson, line 2413 def compare_pieces(a, b) a = $PIECES[a] b = $PIECES[b] # Group writers at the end. if a['writer'] return 1 unless b['writer'] else return -1 if b['writer'] end areqs = a['all_requires'] breqs = b['all_requires'] if areqs.include? b['name'] return areqs.length <=> breqs.length if breqs.include? a['name'] return 1 end return -1 if breqs.include? a['name'] if a['writer'] && b['writer'] if a['scalar'] return -1 unless b['scalar'] else return 1 if b['scalar'] end end # Neither requires the other. Keep pools and pooled items before others. if $pooledreqs.include? a['name'] return -1 unless $pooledreqs.include? b['name'] else return 1 if $pooledreqs.include? b['name'] end if $pooled.include? a['name'] return -1 unless $pooled.include? b['name'] else return 1 if $pooled.include? b['name'] end if $pools.include? a['name'] return -1 unless $pools.include? b['name'] else return 1 if $pools.include? b['name'] end return areqs.length <=> breqs.length unless areqs.length == breqs.length a['name'] <=> b['name'] end
default(spec, field, value)
click to toggle source
# File bin/specificjson, line 2155 def default(spec, field, value) spec[field] = value unless spec.key? field end
defaults(kind, spec)
click to toggle source
# File bin/specificjson, line 2143 def defaults(kind, spec) $DEFAULT[kind].each_pair do |field, value| if spec.key? field if value.is_a?(Array) && !spec[field].is_a?(Array) spec[field] = [ spec[field] ] end else spec[field] = value end end end
license_block(lic2id)
click to toggle source
# File bin/specificjson, line 2484 def license_block(lic2id) blocks = [] lic2id.each_pair do |lic, id| blocks.push %( #if 0 /* #{id}: #{$FILECONTENTS[lic]} */ #endif ) end blocks.join("\n") end
licenses(needed)
click to toggle source
# File bin/specificjson, line 2403 def licenses(needed) lic2id = { } needed.each do |name| lic = $PIECES[name]['license_stored'] next if lic.nil? || lic2id.key?(lic) lic2id[lic] = "License #{lic2id.size + 1}" end lic2id end
load_piece_file(piece, field, directory)
click to toggle source
# File bin/specificjson, line 2119 def load_piece_file(piece, field, directory) filename = piece.fetch(field, nil) if filename.nil? piece[field] = nil piece["#{field}_stored"] = nil return end begin filename = File.realpath(filename, directory) puts filename f = File.new(filename, 'r') content = IO.read(f) f.close rescue StandardError aargh("Failed to open/read: #{filename}", 3) end stored = $FILECONTENTS.key(content) if stored.nil? stored = "c#{$FILECONTENTS.size}" $FILECONTENTS[stored] = content end piece["#{field}_stored"] = stored end
load_spec(filename, root = nil)
click to toggle source
# File bin/specificjson, line 2163 def load_spec(filename, root = nil) begin unless root.nil? filename = File.realpath(filename, root) puts filename end f = File.open(filename, 'r') input = IO.read(f) f.close rescue StandardError aargh("Failed to find/read #{filename}", 3) end begin specs = JSON.parse(input) rescue StandardError begin specs = YAML.safe_load(input, aliases: true) rescue StandardError aargh("#{filename} neither JSON nor YAML.", 3) end end specs end
make_header(spec, piece_names, generated, lic2id)
click to toggle source
# File bin/specificjson, line 2500 def make_header(spec, piece_names, generated, lic2id) h = File.new(spec['header'], 'w') h.puts %(// Auto-generated file. Do not edit. #if !defined(#{spec['header'].upcase.sub('.', '_')}) #define #{spec['header'].upcase.sub('.', '_')} #{license_block(lic2id)} ) h.puts %( #{unique_in_order(piece_names, 'includes').join("\n")} namespace #{spec['namespace']} { #{unique_in_order(piece_names, 'declaration').join("\n")} #{(generated.keys.map { |k| generated[k][:forward].join("\n") }).join("\n")} ) prev = nil piece_names.each do |name| piece = $PIECES[name] next if piece['header_stored'].nil? lic = piece['license_stored'] if lic != prev h.puts h.puts(lic.nil? ? '// Unspecified license.' : "// Under #{lic2id[lic]}.") prev = lic end h.puts h.puts "// Origin: #{piece['header']}" h.puts(piece['header_content']) end generated.each_pair do |typename, object| h.puts %Q( // #{typename} #{object[:extern].join("\n")} #{object[:typedef].join("\n")} #{object[:class].join("\n")} ) end h.puts %Q( } // namespace #{spec['namespace']} #endif) h.close return spec['header'] end
make_source(spec, piece_names, generated, lic2id, header_name)
click to toggle source
# File bin/specificjson, line 2548 def make_source(spec, piece_names, generated, lic2id, header_name) h = File.new(spec['source'], 'w') h.puts %(// Auto-generated file. Do not edit. #{license_block(lic2id)} #define INCLUDED_FROM_GENERATED_SOURCE 1 #include "#{header_name}" #undef INCLUDED_FROM_GENERATED_SOURCE #{unique_in_order(piece_names, 'source_includes').join("\n")} using namespace #{spec['namespace']}; ) prev = nil piece_names.each do |name| piece = $PIECES[name] next if piece['source_stored'].nil? lic = piece['license_stored'] if lic != prev h.puts h.puts(lic.nil? ? '// Unspecified license.' : "// Under #{lic2id[lic]}.") prev = lic end h.puts h.puts "// Origin: #{piece['source']}" h.puts(piece['source_content']) end generated.each_pair do |typename, object| h.puts %( // #{typename} #{object[:extern_src].join("\n")} ) end h.close return spec['source'] end
parserpool_substitutions(needed, namespace)
click to toggle source
# File bin/specificjson, line 2348 def parserpool_substitutions(needed, namespace) $pools = [] $pooled = [] needed.each do |name| piece = $PIECES[name] $pools.push(name) unless piece['poolindexes'].nil? && piece['poolparsers'].nil? && piece['poolparsertypes'].nil? $pooled.push(name) unless piece['pooled'].nil? %w[header source].each do |field| fc = piece["#{field}_stored"] next if fc.nil? piece["#{field}_content"] = String.new($FILECONTENTS[fc]) next if 'specjson' == namespace until piece["#{field}_content"].sub!('specjson::', "#{namespace}::").nil? end end end poolvals = { 'poolindexes' => [], 'poolparsers' => [], 'poolparsertypes' => [] } $pooled.each_index do |k| piece = $PIECES[$pooled[k]] poolvals['poolindexes'].push $pooled[k] poolvals['poolparsers'].push piece['parsername'] poolvals['poolparsertypes'].push "#{piece['parsername']}::Type" [ 'header', 'source' ].each do |field| fc = piece["#{field}_stored"] next if fc.nil? until piece["#{field}_content"].sub!(piece['pooled'], k.to_s).nil? end end end poolvals.each_pair { |k, v| poolvals[k] = v.join(', ') } $pools.each do |name| piece = $PIECES[name] %w[header source].each do |field| fc = piece["#{field}_stored"] next if fc.nil? poolvals.each_pair do |fld, value| until piece["#{field}_content"].sub!(piece[fld], value).nil? end end end end $pooledreqs = [] $pooled.each do |name| piece = $PIECES[name] piece['all_requires'].each do |p| $pooledreqs.push p unless p == name end end $pooledreqs.uniq! end
unique_in_order(piece_names, field)
click to toggle source
# File bin/specificjson, line 2468 def unique_in_order(piece_names, field) values = [] piece_names.each do |name| piece = $PIECES[name] next if piece[field].nil? if piece[field].is_a? String values.push(piece[field]) unless values.include? piece[field] else piece[field].each do |line| values.push(line) unless values.include? line end end end values end
write_function(spec, typename)
click to toggle source
# File bin/specificjson, line 2657 def write_function(spec, typename) object = spec['types'][typename] all_req = true object.each_value do |desc| all_req = false unless desc['required'] end lines = [ %( #if !defined(INCLUDED_FROM_GENERATED_SOURCE) template<typename Sink> void Write(Sink& S, const #{typename}& Value, std::vector<char>& Buffer) { char c = '{'; S.write(&c, 1);) ] lines.push(' bool separated = true;') unless all_req prev_req = nil fields = object.keys # If write order is ever something other than the key one, change it here. fields.each do |field| desc = object[field] fill = '' unless desc['required'] lines.push " if (Value.#{desc['checker']}) {" fill = ' ' end unless prev_req.nil? if all_req || prev_req lines.push "#{fill} c = ',';" lines.push "#{fill} S.write(&c, 1);" elsif !prev_req.nil? lines.push "#{fill} if (!separated) {" lines.push "#{fill} c = ',';" lines.push "#{fill} S.write(&c, 1);" lines.push "#{fill} }" end end lines.push "#{fill} Write(S, #{typename}_#{field}, Buffer);" lines.push "#{fill} c = ':';" lines.push "#{fill} S.write(&c, 1);" lines.push "#{fill} Write(S, Value.#{desc['accessor']}, Buffer);" lines.push("#{fill} separated = false;") unless all_req || field == fields.last lines.push(' }') unless desc['required'] prev_req = desc['required'] end lines.push %( c = '}'; S.write(&c, 1); } #endif // INCLUDED_FROM_GENERATED_SOURCE ) lines.join("\n") end