Ticket #211: split-cncpp-into-c-cpp-1.patch
| File split-cncpp-into-c-cpp-1.patch, 17.9 kB (added by ciaranm, 4 months ago) |
|---|
-
a/ext/ohcount_native/generator.rb
old new 26 26 bat = LineCommentMonoglot.new("bat", '^\\\\s*(?i)REM(?-i)') 27 27 boo = PythonMonoglot.new("boo") 28 28 clearsilver = CMonoglot.new("clearsilver", '#', nil, true, true) 29 cncpp = CMonoglot.new("cncpp", '//', [e('/*'), e('*/')], true, false) 29 c = CMonoglot.new("c", '//', [e('/*'), e('*/')], true, false) 30 cpp = CMonoglot.new("cpp", '//', [e('/*'), e('*/')], true, false) 30 31 csharp = CMonoglot.new("csharp", '//', [e('/*'), e('*/')], true, false) 31 32 css = CMonoglot.new("css", nil, [e('/*'), e('*/')], false, false) 32 33 dylan = CMonoglot.new("dylan", '//', nil, true, false) … … 72 73 bat , 73 74 boo , 74 75 clearsilver , 75 cncpp , 76 c , 77 cpp , 76 78 csharp , 77 79 css , 78 80 dylan , -
a/ext/ohcount_native/ruby_binding.c
old new 104 104 * 105 105 * # Print each line to the console, labeled as code or comments 106 106 * buffer = File.read("helloworld.c") 107 * results = Ohcount::parse(buffer, 'c ncpp') do |language, semantic, line|107 * results = Ohcount::parse(buffer, 'c') do |language, semantic, line| 108 108 * puts "#{semantic.to_s} #{line}" 109 109 * end 110 110 * … … 112 112 * 113 113 * # Print total lines of code 114 114 * buffer = File.read("helloworld.c") 115 * results = Ohcount::parse(buffer, 'c ncpp')115 * results = Ohcount::parse(buffer, 'c') 116 116 * results.each do |result| 117 117 * puts "Lines of #{result.name} code: #{ result.code.split("\n").size }" 118 118 * end -
a/lib/ohcount/detector.rb
old new 35 35 # 36 36 # Example: 37 37 # 38 # # List all C /C++files in the 'src' directory38 # # List all C files in the 'src' directory 39 39 # Dir.entries("src").each do |file| 40 40 # context = Ohcount::SimpleFileContext.new(file) 41 41 # polyglot = Ohcount::Detector.detect(context) 42 # puts "#{file}" if polyglot == 'c ncpp'42 # puts "#{file}" if polyglot == 'c' 43 43 # end 44 44 # 45 45 def self.detect(file_context) 46 46 # start with extension 47 polyglot = EXTENSION_MAP[File.extname(file_context.filename).downcase] 47 polyglot = EXTENSION_MAP[File.extname(file_context.filename)] 48 polyglot = EXTENSION_MAP[File.extname(file_context.filename).downcase] unless polyglot 48 49 case polyglot 49 50 when String 50 51 # simplest case … … 103 104 '.bas' => "visualbasic", 104 105 '.bat' => "bat", 105 106 '.boo' => "boo", 106 '.c' => "cncpp", 107 '.cc' => "cncpp", 108 '.cpp' => "cncpp", 107 '.c' => "c", 108 '.C' => "cpp", 109 '.cc' => "cpp", 110 '.cpp' => "cpp", 109 111 '.css' => "css", 110 '.c++' => "c ncpp",111 '.cxx' => "c ncpp",112 '.c++' => "cpp", 113 '.cxx' => "cpp", 112 114 '.el' => "emacslisp", 113 115 # '.cbl' => "cobol", 114 116 # '.cob' => "cobol", … … 129 131 '.frx' => "visualbasic", 130 132 '.groovy'=> "groovy", 131 133 '.h' => :disambiguate_h_header, 132 '.hpp' => "cncpp", 133 '.h++' => "cncpp", 134 '.H' => "cpp", 135 '.hpp' => "cpp", 136 '.h++' => "cpp", 134 137 '.hs' => "haskell", 135 '.hxx' => "c ncpp",136 '.hh' => "c ncpp",138 '.hxx' => "cpp", 139 '.hh' => "cpp", 137 140 '.hrl' => "erlang", 138 141 '.htm' => "html", 139 142 '.html' => "html", … … 216 219 matlab > 0 ? 'matlab' : 'objective_c' 217 220 end 218 221 219 # For *.h files, differentiates C /C++ fromObjective-C.222 # For *.h files, differentiates C, C++ and Objective-C. 220 223 # 221 224 # This is done with a weighted heuristic that 222 225 # scans the *.h file contents for Objective-C keywords, 223 # and also checks for the presence of matching *.m files. 226 # C++ keywords and C++ headers, and also checks for the 227 # presence of matching *.m files. 224 228 def self.disambiguate_h_header(file_context) 225 229 buffer = file_context.contents 226 230 … … 232 236 file_context.filenames.extend(ContainsM) 233 237 file_context.filenames.contains_m = file_context.filenames.select { |a| a =~ /\.m$/ }.any? 234 238 end 235 return 'cncpp'unless file_context.filenames.contains_m239 return disambiguate_c_cpp(buffer) unless file_context.filenames.contains_m 236 240 237 241 # if the dir contains a matching *.m file, likely objective_c 238 242 if file_context.filename =~ /\.h$/ … … 244 248 objective_c_signatures = /(^\s*@interface)|(^\s*@end)/ 245 249 objective_c += lines_matching(buffer, objective_c_signatures) 246 250 247 return objective_c > 1 ? 'objective_c' : 'cncpp' 251 return objective_c > 1 ? 'objective_c' : disambiguate_c_cpp(buffer) 252 end 253 254 # A map of headers that indicate C++, but that do not have C++-specific file 255 # extensions. This list is made from the Standard, plus Technical Report 1. 256 CPP_HEADERS_MAP = %w[ 257 algorithm 258 array 259 bitset 260 cassert 261 ccomplex 262 cctype 263 cerrno 264 cfenv 265 cfloat 266 cinttypes 267 ciso646 268 climits 269 clocale 270 cmath 271 csetjmp 272 csignal 273 cstdarg 274 cstdbool 275 cstddef 276 cstdint 277 cstdio 278 cstdlib 279 cstring 280 ctgmath 281 ctime 282 cwchar 283 cwctype 284 deque 285 exception 286 fstream 287 functional 288 iomanip 289 ios 290 iosfwd 291 iostream 292 istream 293 iterator 294 limits 295 list 296 locale 297 map 298 memory 299 new 300 numeric 301 ostream 302 queue 303 random 304 regex 305 set 306 sstream 307 stack 308 stdexcept 309 streambuf 310 string 311 system_error 312 tuple 313 type_traits 314 typeinfo 315 unordered_map 316 unordered_set 317 utility 318 valarray 319 vector 320 tr1/array 321 tr1/ccomplex 322 tr1/cctype 323 tr1/cfenv 324 tr1/cfloat 325 tr1/cinttypes 326 tr1/climits 327 tr1/cmath 328 tr1/complex 329 tr1/cstdarg 330 tr1/cstdbool 331 tr1/cstdint 332 tr1/cstdio 333 tr1/cstdlib 334 tr1/ctgmath 335 tr1/ctime 336 tr1/cwchar 337 tr1/cwctype 338 tr1/memory 339 tr1/random 340 tr1/regex 341 tr1/tuple 342 tr1/type_traits 343 tr1/unordered_map 344 tr1/unordered_set 345 tr1/utility 346 ].inject({}) { | h, k | h[k] = true ; h } 347 348 # A map of keywords that indicate C++. 349 CPP_KEYWORDS_MAP = %w[ 350 template 351 typename 352 class 353 namespace 354 ].inject({}) { | h, k | h[k] = true ; h } 355 356 # For *.h files that we know aren't Objective-C, differentiates C and C++. 357 # 358 # This is done with a weighted heuristic that 359 # scans the *.h file contents for C++ keywords and C++ headers. 360 def self.disambiguate_c_cpp(buffer) 361 # Look for C++ headers 362 return 'cpp' if extract_c_cpp_headers(buffer).detect do | header | 363 EXTENSION_MAP[File.extname(header)] == 'cpp' or CPP_HEADERS_MAP.include? header 364 end 365 366 # Look for C++ keywords. This could check for comments, but doesn't. 367 return 'cpp' if buffer.find do | line | 368 line.split(/\W/).find do | word | 369 CPP_KEYWORDS_MAP.include? word 370 end 371 end 372 373 # Nothing to suggest C++ 374 'c' 375 end 376 377 # Return a list of files included in a C or C++ source file. 378 def self.extract_c_cpp_headers(buffer) 379 buffer.map do | line | 380 m = line.match(/^#\s*include\s+[<"](.*)[>"]/) and m[1] 381 end.find_all { | a | a } 248 382 end 249 383 250 384 # Tests whether the provided buffer contains binary or text content. -
a/lib/ohcount/sloc_info.rb
old new 44 44 'awk' => {:nice_name => 'AWK' , :category => 0}, 45 45 'bat' => {:nice_name => 'DOS batch script' , :category => 0}, 46 46 'boo' => {:nice_name => 'Boo' , :category => 0}, 47 'cncpp' => {:nice_name => 'C/C++' , :category => 0}, 47 'c' => {:nice_name => 'C' , :category => 0}, 48 'cpp' => {:nice_name => 'C++' , :category => 0}, 48 49 'clearsilver' => {:nice_name => 'ClearSilver' , :category => 0}, 49 50 'csharp' => {:nice_name => 'C#' , :category => 0}, 50 51 'css' => {:nice_name => 'CSS' , :category => 1}, -
/dev/null
old new 1 #include <foo/foo.hh> 2 3 foo::Foo get_foo(); 4 -
/dev/null
old new 1 namespace monkey { 2 template <typename> struct Monkey; 3 } 4 -
/dev/null
old new 1 #include <string> 2 3 std::string foo(); -
/dev/null
old new 1 #include <sys/types.h> 2 #include <sys/stat.h> 3 #include <unistd.h> 4 5 int superstat(const char * path, struct stat * buf); -
/dev/null
old new -
/dev/null
old new 1 #include <cmqc.h> /* MQ API header file */ 2 #define NUMBEROFSELECTORS 2 3 const MQHCONN Hconn = MQHC_DEF_HCONN; 4 static void InquireGetAndPut(char *Message, 5 PMQHOBJ pHobj, 6 char *Object) 7 { 8 MQLONG SelectorCount = NUMBEROFSELECTORS; 9 MQLONG IntAttrCount = NUMBEROFSELECTORS; 10 MQLONG CharAttrLength = 0; 11 MQCHAR *CharAttrs ; 12 MQLONG SelectorsTable[NUMBEROFSELECTORS]; 13 MQLONG IntAttrsTable[NUMBEROFSELECTORS]; 14 MQLONG CompCode; /* Completion code */ 15 MQLONG Reason; /* Qualifying reason */ 16 SelectorsTable[0] = MQIA_INHIBIT_GET; 17 SelectorsTable[1] = MQIA_INHIBIT_PUT; 18 MQINQ(Hconn, 19 *pHobj, 20 SelectorCount, 21 SelectorsTable, 22 IntAttrCount, 23 IntAttrsTable, 24 CharAttrLength, 25 CharAttrs, 26 &CompCode, 27 &Reason); 28 if (CompCode != MQCC_OK) 29 { 30 sprintf(Message, MESSAGE_4_E, 31 ERROR_IN_MQINQ, CompCode, Reason); 32 SetMsg(Message); 33 } 34 else 35 { 36 } /* end if CompCode */ -
/dev/null
old new 1 // 2 /* Declare local variables */ 3 /* */ 4 /* Number of selectors */ 5 /* Number of int attrs */ 6 /* Length of char attribute buffer */ 7 /* Character attribute buffer */ 8 /* attribute selectors */ 9 /* integer attributes */ 10 /* */ 11 /* Open the queue. If successful, do the inquire */ 12 /* call. */ 13 /* */ 14 /* */ 15 /* Initialize the variables for the inquire */ 16 /* call: */ 17 /* - Set SelectorsTable to the attributes whose */ 18 /* status is */ 19 /* required */ 20 /* - All other variables are already set */ 21 /* */ 22 /* */ 23 /* Issue the inquire call */ 24 /* Test the output of the inquire call. If the */ 25 /* call failed, display an error message */ 26 /* showing the completion code and reason code,*/ 27 /* otherwise display the status of the */ 28 /* INHIBIT-GET and INHIBIT-PUT attributes */ 29 /* */ 30 /* Process the changes */ -
/dev/null
old new -
/dev/null
old new 1 #include <cmqc.h> /* MQ API header file */2 #define NUMBEROFSELECTORS 23 const MQHCONN Hconn = MQHC_DEF_HCONN;4 static void InquireGetAndPut(char *Message,5 PMQHOBJ pHobj,6 char *Object)7 {8 MQLONG SelectorCount = NUMBEROFSELECTORS;9 MQLONG IntAttrCount = NUMBEROFSELECTORS;10 MQLONG CharAttrLength = 0;11 MQCHAR *CharAttrs ;12 MQLONG SelectorsTable[NUMBEROFSELECTORS];13 MQLONG IntAttrsTable[NUMBEROFSELECTORS];14 MQLONG CompCode; /* Completion code */15 MQLONG Reason; /* Qualifying reason */16 SelectorsTable[0] = MQIA_INHIBIT_GET;17 SelectorsTable[1] = MQIA_INHIBIT_PUT;18 MQINQ(Hconn,19 *pHobj,20 SelectorCount,21 SelectorsTable,22 IntAttrCount,23 IntAttrsTable,24 CharAttrLength,25 CharAttrs,26 &CompCode,27 &Reason);28 if (CompCode != MQCC_OK)29 {30 sprintf(Message, MESSAGE_4_E,31 ERROR_IN_MQINQ, CompCode, Reason);32 SetMsg(Message);33 }34 else35 {36 } /* end if CompCode */ -
/dev/null
old new 1 //2 /* Declare local variables */3 /* */4 /* Number of selectors */5 /* Number of int attrs */6 /* Length of char attribute buffer */7 /* Character attribute buffer */8 /* attribute selectors */9 /* integer attributes */10 /* */11 /* Open the queue. If successful, do the inquire */12 /* call. */13 /* */14 /* */15 /* Initialize the variables for the inquire */16 /* call: */17 /* - Set SelectorsTable to the attributes whose */18 /* status is */19 /* required */20 /* - All other variables are already set */21 /* */22 /* */23 /* Issue the inquire call */24 /* Test the output of the inquire call. If the */25 /* call failed, display an error message */26 /* showing the completion code and reason code,*/27 /* otherwise display the status of the */28 /* INHIBIT-GET and INHIBIT-PUT attributes */29 /* */30 /* Process the changes */ -
a/test/unit/c_test.rb
old new 3 3 class Ohcount::CTest < Ohcount::Test 4 4 5 5 def test_comments 6 lb = [Ohcount::LanguageBreakdown.new("c ncpp", "", "//comment", 0)]7 assert_equal lb, Ohcount::parse(" //comment", "c ncpp")6 lb = [Ohcount::LanguageBreakdown.new("c", "", "//comment", 0)] 7 assert_equal lb, Ohcount::parse(" //comment", "c") 8 8 end 9 9 10 10 def test_empty_comments 11 lb = [Ohcount::LanguageBreakdown.new("c ncpp", "","//\n", 0)]12 assert_equal lb, Ohcount::parse(" //\n", "c ncpp")11 lb = [Ohcount::LanguageBreakdown.new("c", "","//\n", 0)] 12 assert_equal lb, Ohcount::parse(" //\n", "c") 13 13 end 14 14 15 15 16 16 def test_block_comment 17 lb = [Ohcount::LanguageBreakdown.new("c ncpp", "","/*c*/", 0)]18 assert_equal lb, Ohcount::parse("/*c*/", "c ncpp")17 lb = [Ohcount::LanguageBreakdown.new("c", "","/*c*/", 0)] 18 assert_equal lb, Ohcount::parse("/*c*/", "c") 19 19 end 20 20 21 21 def test_comprehensive -
a/test/unit/detector_test.rb
old new 37 37 end 38 38 39 39 def test_detect_polyglot 40 assert_equal "cncpp", do_detect("foo.c") 40 assert_equal "c", do_detect("foo.c") 41 assert_equal "c", do_detect("uses_no_cpp.h") 42 assert_equal "cpp", do_detect("uses_cpp_headers.h") 43 assert_equal "cpp", do_detect("uses_cpp_stdlib_headers.h") 44 assert_equal "cpp", do_detect("uses_cpp_keywords.h") 41 45 assert_equal "ruby", do_detect("foo.rb") 42 46 assert_equal "matlab", do_detect("foo_matlab.m", ["foo_matlab.m", "bar.m", "README"]) 43 47 assert_equal "objective_c", do_detect("foo_objective_c.m", ["foo_objective_c.m", "bar.h", "README"]) … … 52 56 end 53 57 54 58 def test_upper_case_extensions 55 assert_equal "c ncpp", do_detect("foo_upper_case.C")59 assert_equal "cpp", do_detect("foo_upper_case.C") 56 60 assert_equal "ruby", do_detect("foo_upper_case.RB") 57 61 end 58 62 -
a/test/unit/diff_test.rb
old new 24 24 src_dir = File.dirname(__FILE__) + '/../src_dir/' 25 25 sloc_infos = Ohcount.diff_files(src_dir + 'diff2_old.c', src_dir + 'diff2_new.c') 26 26 27 c = Ohcount::SlocInfo.new('c ncpp')27 c = Ohcount::SlocInfo.new('c') 28 28 c.code_added, c.code_removed = [1,1] 29 29 c.comments_added, c.comments_removed = [1,1] 30 30