Skip to content

Commit

Permalink
Merge pull request github-linguist#162 from horchler/detect-matlab
Browse files Browse the repository at this point in the history
More robust heuristics for .m files and 3 new Matlab tests. Finally.
  • Loading branch information
josh committed May 8, 2012
2 parents f0eace7 + 354e1fc commit f56fbff
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 10 deletions.
22 changes: 12 additions & 10 deletions lib/linguist/blob_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -451,24 +451,26 @@ def guess_h_language
# Internal: Guess language of .m files.
#
# Objective-C heuristics:
# * Keywords
# * Keywords ("#import", "#include", "#ifdef", #define, "@end") or "//" and opening "\*" comments
#
# Matlab heuristics:
# * Leading function keyword
# * Leading "function " of "classdef " keyword
# * "%" comments
#
# Note: All "#" keywords, e.g., "#import", are guaranteed to be Objective-C. Because the ampersand
# is used to created function handles and anonymous functions in Matlab, most "@" keywords are not
# safe heuristics. However, "end" is a reserved term in Matlab and can't be used to create a valid
# function handle. Because @end is required to close any @implementation, @property, @interface,
# @synthesize, etc. directive in Objective-C, only @end needs to be checked for.
#
# Returns a Language.
def guess_m_language
# Objective-C keywords
if lines.grep(/^#import|@(interface|implementation|property|synthesize|end)/).any?
# Objective-C keywords or comments
if lines.grep(/^#(import|include|ifdef|define)|@end/).any? || lines.grep(/^\s*\/\//).any? || lines.grep(/^\s*\/\*/).any?
Language['Objective-C']

# File function
elsif lines.first.to_s =~ /^function /
Language['Matlab']

# Matlab comment
elsif lines.grep(/^%/).any?
# Matlab file function or class or comments
elsif lines.first.grep(/^\s*(function |classdef )/).any? || lines.grep(/^\s*%/).any?
Language['Matlab']

# Fallback to Objective-C, don't want any Matlab false positives
Expand Down
29 changes: 29 additions & 0 deletions test/fixtures/matlab_class.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
classdef matlab_class
properties
R;
G;
B;
end
methods
function obj = matlab_class(r,g,b)
obj.R = r;
obj.G = g;
obj.B = b;
end
function disp(obj)
disp(['Red: ' num2str(obj.R) ...
', Green: ' num2str(obj.G) ...
', Blue: ' num2str(obj.B)]);
end
end
enumeration
red (1,0,0)
green (0,1,0)
blue (0,0,1)
cyan (0,1,1)
magenta (1,0,1)
yellow (1,1,0)
black (0,0,0)
white (1,1,1)
end
end
33 changes: 33 additions & 0 deletions test/fixtures/matlab_function2.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
function ret = matlab_function2(A,B)
% Simple function that combines two values using function handles and displays
% the return value

% create function handles
fun1=@interface;
fun2=@implementation;
fun3=@property;
fun4=@synthesize;

% use function handles
ret = fun1(A)+fun2(A)+fun3(B)+fun4(B);

% Display the return value
disp('Return value in function');
disp(ret);


function A=interface(A)
% simple sub-function with same name Objective-C @keyword
A=2*A;

function A=implementation(A)
% simple sub-function with same name Objective-C @keyword
A=A^2;

function B=property(B)
% simple sub-function with same name Objective-C @keyword
B=2*B;

function B=synthesize(B)
% simple sub-function with same name Objective-C @keyword
B=B^2;
13 changes: 13 additions & 0 deletions test/fixtures/matlab_script2.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
% Matlab example script 2
% Comments precended with arbitrary whitespace (spaces or tabs)

%Call matlab_function function which resides in the same directory

value1 = 5 % semicolon at end of line is not mandatory, only suppresses output to command line.
value2 = 3

% Calculate sum of value1 and value2
result = matlab_function(value1,value2);

disp('called from script')
disp(result);
3 changes: 3 additions & 0 deletions test/test_blob.rb
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ def test_language
assert_equal Language['Objective-C'], blob("hello.m").language
assert_equal Language['Matlab'], blob("matlab_function.m").language
assert_equal Language['Matlab'], blob("matlab_script.m").language
assert_equal Language['Matlab'], blob("matlab_function2.m").language
assert_equal Language['Matlab'], blob("matlab_script2.m").language
assert_equal Language['Matlab'], blob("matlab_class.m").language

# .r disambiguation
assert_equal Language['R'], blob("hello-r.R").language
Expand Down

0 comments on commit f56fbff

Please sign in to comment.