node/lib/metasm/metasm/preprocessor.rb
# handles the '#include' directive, which will insert a new file content in the token stream
handles the '#include' directive, which will insert a new file content in the token stream
handles the ' #include ' directive which will insert a new file content in the token stream
def directive_include(cmd, skipspc)
		raise cmd, 'nested too deeply' if backtrace.length > 200	
		nil while tok = readtok and tok.type == :space
		raise tok || cmd, 'pp syntax error' if not tok or (tok.type != :quoted and (tok.type != :punct or tok.raw != '<'))
		if tok.type == :quoted
			ipath = tok.value
			if @filename[0] == ?< or @backtrace.find { |btf, *a| btf[0] == ?< }
				path = nil
				if not @include_search_path.find { |d| ::File.exist?(path = ::File.join(d, ipath)) } ||
					@include_search_path.find { |d| path = file_exist_nocase(::File.join(d, ipath)) } ||
					path = file_exist_nocase(::File.join(::File.dirname(@filename[1..-2]), ipath))
					path = nil
				end
			elsif ipath[0] != ?/
				path = ::File.join(::File.dirname(@filename[1..-2]), ipath) if ipath[0] != ?/
				path = file_exist_nocase(path || ipath) if not ::File.exist?(path || ipath)
			else
				path = ipath
				path = file_exist_nocase(path) if not ::File.exist? path
			end
		else
			ipath = ''
			while tok = readtok_nopp and (tok.type != :punct or tok.raw != '>')
				raise cmd, 'syntax error' if tok.type == :eol
				ipath << tok.raw
			end
			raise cmd, 'pp syntax error, unterminated path' if not tok
			if ipath[0] != ?/
				path = nil
				isp = @include_search_path
				if cmd.raw == 'include_next'
					raise self, 'include_next sux' if not idx = isp.find { |d| @filename[1, d.length] == d }
					isp = isp[isp.index(idx)+1..-1]
				end
				if not isp.find { |d| ::File.exist?(path = ::File.join(d, ipath)) } ||
					isp.find { |d| path = file_exist_nocase(::File.join(d, ipath)) }
					path = nil
				end
			end
		end
		eol = nil
		raise eol if eol = skipspc[] and eol.type != :eol
		unreadtok eol
		return if cmd.raw == 'include_next' and not path and not @hooked_include[ipath]	
		if not @pragma_once[path || ipath]
			@backtrace << [@filename, @lineno, @text, @pos, @queue, @ifelse_nesting.length]
			-style autodetect
			 the headers we already parsed may have needed a prepare_gcc...
			if ipath == 'stddef.h' and not path and not @hooked_include[ipath]
				tk = tok.dup
				tk.raw = 'prepare_gcc'
				@pragma_callback[tk]
				if @hooked_include[ipath]
					puts "metasm pp: autodetected gcc-style headers" if $VERBOSE
				end
			end
			if @hooked_include[ipath]
				path = '<hooked>/'+ipath
				puts "metasm preprocessor: including #{path}" if $DEBUG
				@text = @hooked_include[ipath]
			else
				puts "metasm preprocessor: including #{path}" if $DEBUG
				raise cmd, "No such file or directory #{ipath.inspect}" if not path or not ::File.exist? path
				raise cmd, 'filename too long' if path.length > 4096		
				@text = ::File.read(path)
			end
			if tok.type == :quoted
				@filename = '"' + path + '"'
			else
				@filename = '<' + path + '>'
			end
			@lineno = 1
			@pos = 0
			@queue = []
		else
			puts "metasm preprocessor: not reincluding #{path} (pragma once)" if $DEBUG
		end
	end
def directive_include ( cmd , skipspc ) raise cmd , 'nested too deeply' if backtrace . length > 200 nil while tok = readtok and tok . type == :space raise tok || cmd , 'pp syntax error' if not tok or ( tok . type != :quoted and ( tok . type != :punct or tok . raw != '<' ) ) if tok . type == :quoted ipath = tok . value if @filename [ 0 ] == ?< or @backtrace . find { | btf , * a | btf [ 0 ] == ?< } path = nil if not @include_search_path . find { | d | :: File . exist? ( path = :: File . join ( d , ipath ) ) } || @include_search_path . find { | d | path = file_exist_nocase ( :: File . join ( d , ipath ) ) } || path = file_exist_nocase ( :: File . join ( :: File . dirname ( @filename [ 1 .. - 2 ] ) , ipath ) ) path = nil end elsif ipath [ 0 ] != ?/ path = :: File . join ( :: File . dirname ( @filename [ 1 .. - 2 ] ) , ipath ) if ipath [ 0 ] != ?/ path = file_exist_nocase ( path || ipath ) if not :: File . exist? ( path || ipath ) else path = ipath path = file_exist_nocase ( path ) if not :: File . exist? path end else ipath = '' while tok = readtok_nopp and ( tok . type != :punct or tok . raw != '>' ) raise cmd , 'syntax error' if tok . type == :eol ipath << tok . raw end raise cmd , 'pp syntax error, unterminated path' if not tok if ipath [ 0 ] != ?/ path = nil isp = @include_search_path if cmd . raw == 'include_next' raise self , 'include_next sux' if not idx = isp . find { | d | @filename [ 1 , d . length ] == d } isp = isp [ isp . index ( idx ) + 1 .. - 1 ] end if not isp . find { | d | :: File . exist? ( path = :: File . join ( d , ipath ) ) } || isp . find { | d | path = file_exist_nocase ( :: File . join ( d , ipath ) ) } path = nil end end end eol = nil raise eol if eol = skipspc [ ] and eol . type != :eol unreadtok eol return if cmd . raw == 'include_next' and not path and not @hooked_include [ ipath ] if not @pragma_once [ path || ipath ] @backtrace << [ @filename , @lineno , @text , @pos , @queue , @ifelse_nesting . length ] if ipath == 'stddef.h' and not path and not @hooked_include [ ipath ] tk = tok . dup tk . raw = 'prepare_gcc' @pragma_callback [ tk ] if @hooked_include [ ipath ] puts "metasm pp: autodetected gcc-style headers" if $VERBOSE end end if @hooked_include [ ipath ] path = '<hooked>/' + ipath puts "metasm preprocessor: including #{path}" if $DEBUG @text = @hooked_include [ ipath ] else puts "metasm preprocessor: including #{path}" if $DEBUG raise cmd , "No such file or directory #{ipath.inspect}" if not path or not :: File . exist? path raise cmd , 'filename too long' if path . length > 4096 @text = :: File . read ( path ) end if tok . type == :quoted @filename = '"' + path + '"' else @filename = '<' + path + '>' end @lineno = 1 @pos = 0 @queue = [ ] else puts "metasm preprocessor: not reincluding #{path} (pragma once)" if $DEBUG end end
handles the '#include' directive, which will insert a new file content in the token stream
handles the ' #include ' directive which will insert a new file content in the token stream
# gcc # allow preprocessing # XXX local include from a std include... (kikoo windows.h !) # no more preprocessing : allow comments/multiple space/etc # XXX # gcc-style autodetect # XXX the headers we already parsed may have needed a prepare_gcc... # maybe restart parsing ? # gcc # @filename[-1] used in trace_macros to distinguish generic/specific files
cmd
skipspc