⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sainity

📁 Linux系统下的P2P协议下载客户端
💻
📖 第 1 页 / 共 2 页
字号:
		@desc = "Using variations of (x ? true : false) or (x ? false : true) is just plain stupid."	end	def parse_file(file, lines) 		results = lines.select do |line|			line.text =~ /\?\s*(true|false)\s*:\s*(true|false)/i					end		add_results( file, results )	endendclass LoopOnConstant < SainityCheck	def initialize		super			@name  = "LoopingOnConstant"		@title = "Looping On Constant"		@type  = "Garbage"		@desc  = "This checks detects loops that evaluate constant values "		@desc += "(true,false,0..) or \"for\" loops with no conditionals. all "		@desc += "are often a sign of poor code and in most cases can be avoided "		@desc += "or replaced with more elegant code."	end	def parse_file(file, lines) 		results = lines.select do |line|			line.text =~ /while\s*\(\s*([0-9]+|true|false)\s*\)/i or			line.text =~ /for\s*\([^;]*;\s*;[^;]*\)/		end		add_results( file, results )	endendclass MissingImplementation < SainityCheck	def initialize		super		@name  = "MissingImplementation"		@title = "Missing Function Implementation"		@type  = "Garbage"		@desc  = "Forgetting to remove a function-definition after having removed it "		@desc += "from the .cpp file only leads to cluttered header files. The only "		@desc += "case where non-implemented functions should be used is when it is "		@desc += "necesarry to prevent usage of for instance assignment between "		@desc += "instances of a class."		@declarations = Array.new		@definitions = Array.new	end	def results		@definitions.each do |definition|			@declarations.delete_if do |pair|				pair.first == definition			end		end						return @declarations.map do |pair|			Result.new( self, pair.last.first, pair.last.last )		end	end	def parse_file(file, lines)		if file =~ /\.h$/ then			level = 0			tree = Array.new						lines.each do |line|				level += line.text.count( "{" ) - line.text.count( "}" )							tree.delete_if do |struct| 					struct.first > level				end								if line.text !~ /^\s*\/\// and line.text !~ /^\s*#/ and line.text !~ /typedef/ then					if line.text =~ /^\s*(class|struct)\s+/ and line.text.count( ";" ) == 0 then						cur_level = level;												if line.text.count( "{" ) == 0 then							cur_level += 1						end												entry = [ cur_level, line.text.scan( /^\s*(class|struct)\s+([^\:{;]+)/ ).first.last.split.last ]										tree << entry					elsif line.text =~ /;\s*$/ and line.text.count( "{" ) == 0 then						# No pure virtual functions and no return(blah) calls (which otherwise can fit the requirements)						if line.text !~ /=\s*0\s*;\s*$/ and line.text !~ /return/ then							re = /^\s*(virtual\s+|static\s+|inline\s+|)\w+(\s+[\*\&]?|[\*\&]\s+)(\w+)\(/.match( line.text )								if re and level > 0 and tree.last then								@declarations << [ tree.last.last + "::" + re[ re.length - 1 ], [ file, line ] ]							end						end					end				end			end		else			lines.each do |line|				if line.text =~ /\b\w+::\w+\s*\([^;]+$/					@definitions << line.text.scan( /\b(\w+::\w+)\s*\([^;]+$/ ).first.first				end			end			end	endend# List of enabled filtersfilterList = Array.newfilterList.push CompareAgainstEmptyString.newfilterList.push AssignmentToEmptyString.newfilterList.push NoIfNDef.newfilterList.push ThisDeference.newfilterList.push Assert.newfilterList.push PassByValue.newfilterList.push CStr.newfilterList.push IfNotDefined.newfilterList.push GPLLicense.newfilterList.push Copyright.newfilterList.push PartOfAmule.newfilterList.push MissingBody.newfilterList.push Translation.newfilterList.push IfZero.newfilterList.push InlinedIfTrue.newfilterList.push LoopOnConstant.newfilterList.push MissingImplementation.new# Sort enabled filters by type and name. The reason why this is done here is# because it's much easier than manually resorting every time I add a filter# or change the name or type of an existing filter.filterList.sort! do |x,y|	cmp = x.type <=> y.type		if cmp == 0 then		x.title <=> y.title	else		cmp	endenddef parse_files( path, filters )	filters = filters.dup	require "find"	Find.find( path ) do |filename|		if filename =~ /\.(cpp|h)$/ and not filename =~ /CryptoPP\./			File.open(filename, "r") do |aFile|				# Read lines and add line-numbers				lines = Array.new				aFile.each_line do |line|					lines.push( Line.new( aFile.lineno, line ) )				end				lines.freeze				# Check the file against each filter				filters.each do |filter|					# Process the file with this filter					filter.parse_file( filename, lines )				end			end		end	end	results = Array.new	filters.each do |filter|		results += filter.results	end	resultsend# Helper-functiondef get_val( key, list )	if not list.last or list.last.first != key then		list << [ key, Array.new ]	end		list.last.lastenddef create_result_tree( path, filters )	# Gather the results	results = parse_files( path, filters )		# Sort the results by the following sequence of variables: Path -> File -> Filter -> Line	results.sort! do |a, b|		if (a.file_path <=> b.file_path) == 0 then			if (a.file_name <=> b.file_name) == 0 then				if (a.type.title <=> b.type.title) == 0 then					a.line.number <=> b.line.number				else					a.type.title <=> b.type.title				end			else				a.file_name <=> b.file_name			end		else			a.file_path <=> b.file_path		end	end	# Create a tree of results: [ Path, [ File, [ Filter, [ Line ] ] ] ]	result_tree = Array.new	results.each do |result|		get_val( result.type, get_val( result.file_name, get_val( result.file_path, result_tree ) ) ) << result	end	result_treeenddef create_filter_tree( filters )	# Change the filterList to a tree: [ Type, [ Filter ] ]	filter_tree = Array.new	filters.each do |filter|		get_val( filter.type, filter_tree ) << filter	end	filter_treeend# Converts a number to a string and pads with zeros so that length becomes at least 5def PadNum( number )	num = number.to_s	if ( num.size < 5 ) 		( "0" * ( 5 - num.size ) ) + num	else		num	endend# Helper-function that escapes some chars to HTML codesdef HTMLEsc( str ) 	str.gsub!( /\&/, "&amp;"  )	str.gsub!( /\"/, "&quot;" )	str.gsub!( /</,  "&lt;"   )	str.gsub!( />/,  "&gt;"   )	str.gsub!( /\n/, "<br>"   )	str.gsub( /\t/,  "&nbsp;" )end# Fugly output code goes here# ... Abandon hope, yee who read past here# TODO Enable use of templates.# TODO Abandon hope.def OutputHTML( filters, results )	text  = "<html>	<head>		<STYLE TYPE=\"text/css\">		<!--			.dir {				background-color: \#A0A0A0;				padding-left: 10pt;				padding-right: 10pt;			}			.file {				background-color: \#838383;				padding-left: 10pt;				padding-right: 10pt;			}			.filter {				background-color: #757575;				padding-left: 10pt;				padding-right: 10pt;				padding-top: 5pt;			}			-->		</STYLE>	</head>	<body bgcolor=\"\#BDBDBD\">		<h1>Filters</h1>		<dl>"	# List the filters	filters.each do |filterType|		text += "			<dt><b>#{filterType.first}</b></dt>			<dd>				<dl>"		filterType.last.each do |filter|			text += "					<dt id=\"#{filter.name}\"><i>#{filter.title}</i></dt>					<dd>						#{HTMLEsc(filter.desc)}<p>					</dd>"		end		text +="				</dl>			</dd>"	end	text += "		</dl>			<p>			<h1>Directories</h1>		<ul>"	# List the directories	results.each do |dir|		text +="			<li>				<a href=\"\##{dir.first}\">#{dir.first}</a>			</li>"	end	text += "		</ul>		<p>			<h1>Results</h1>"	results.each do |dir|		text += "		<div class=\"dir\">			<h2 id=\"#{dir.first}\">#{dir.first}</h2>"		dir.last.each do |file|			text += "			<div class=\"file\">				<h3>#{file.first}</h3>				<ul>"						file.last.each do |filter|				text += "					<li>						<div class=\"filter\">							<b><a href=\"\##{filter.first.name}\">#{filter.first.title}</a></b>							<ul>"							filter.last.each do |result|					if result.line then						text += "								<li><b>#{PadNum(result.line.number)}:</b> #{HTMLEsc(result.line.text.strip)}</li>"					end				end				text +="							</ul>						</div>					</li>"			end			text += "				</ul>			</div>"		end				text += "		</div>		<p>"	end	text += "	</body></html>"	return text;end# Columnizing, using the http://www.rubygarden.org/ruby?UsingTestUnit example because I'm lazy# TODO Rewrite it to better support newlines and stuffdef Columnize( text, width, indent )	return indent + text.scan(/(.{1,#{width}})(?: |$)/).join("\n#{indent}")end# Fugly output code also goes here, this is a bit more sparse than the HTML stuffdef OutputTEXT( filters, results )		# List the filters	text = "Filters\n"	filters.each do |filterType|		text += "\t* #{filterType.first}\n"				filterType.last.each do |filter|			text += "\t\t- #{filter.title}\n"					text += Columnize( filter.desc, 80, "\t\t\t" ) + "\n\n"		end	end	# List the directories	text += "\n\nDirectories\n"	results.each do |dir|		text += "\t#{dir.first}\n"	end	text += "\n\nResults\n"	# To avoid bad readability, I only use fullpaths here instead of sections per dir	results.each do |dir|		dir.last.each do |file|			text += "\t#{dir.first}#{file.first}\n"			file.last.each do |filter|				text += "\t\t* #{filter.first.title}\n"				filter.last.each do |result|					if result.line then						text += "\t\t\t#{PadNum(result.line.number)}: #{result.line.text.strip}\n"					end				end			end			text += "\n"		end	end	return text;end#TODO Improved parameter-handling, add =<file> for the outputing to a fileARGV.each do |param|	case param		when "--text" then 			puts OutputTEXT( create_filter_tree( filterList ), create_result_tree( ".", filterList ) )		when "--html" then 			puts OutputHTML( create_filter_tree( filterList ), create_result_tree( ".", filterList ) )	endend

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -