diff --git a/lib/linguist/file_blob.rb b/lib/linguist/file_blob.rb
index 7e7f1acd..bc475023 100644
--- a/lib/linguist/file_blob.rb
+++ b/lib/linguist/file_blob.rb
@@ -52,5 +52,20 @@ module Linguist
def size
File.size(@path)
end
+
+ # Public: Get file extension.
+ #
+ # Returns a String.
+ def extension
+ # File.extname returns nil if the filename is an extension.
+ extension = File.extname(name)
+ basename = File.basename(name)
+ # Checks if the filename is an extension.
+ if extension.empty? && basename[0] == "."
+ basename
+ else
+ extension
+ end
+ end
end
end
diff --git a/lib/linguist/language.rb b/lib/linguist/language.rb
index f1836721..b2245b87 100644
--- a/lib/linguist/language.rb
+++ b/lib/linguist/language.rb
@@ -109,7 +109,8 @@ module Linguist
# A bit of an elegant hack. If the file is executable but extensionless,
# append a "magic" extension so it can be classified with other
# languages that have shebang scripts.
- if File.extname(name).empty? && blob.mode && (blob.mode.to_i(8) & 05) == 05
+ extension = FileBlob.new(name).extension
+ if extension.empty? && blob.mode && (blob.mode.to_i(8) & 05) == 05
name += ".script!"
end
@@ -189,7 +190,8 @@ module Linguist
#
# Returns all matching Languages or [] if none were found.
def self.find_by_filename(filename)
- basename, extname = File.basename(filename), File.extname(filename)
+ basename = File.basename(filename)
+ extname = FileBlob.new(filename).extension
langs = @filename_index[basename] +
@extension_index[extname]
langs.compact.uniq
diff --git a/lib/linguist/samples.json b/lib/linguist/samples.json
index 8ea2394a..c78ed491 100644
--- a/lib/linguist/samples.json
+++ b/lib/linguist/samples.json
@@ -740,6 +740,9 @@
"Nginx": [
"nginx.conf"
],
+ "PHP": [
+ ".php"
+ ],
"Perl": [
"ack"
],
@@ -782,6 +785,9 @@
".gvimrc",
".vimrc"
],
+ "XML": [
+ ".cproject"
+ ],
"YAML": [
".gemrc"
],
@@ -791,8 +797,8 @@
"exception.zep.php"
]
},
- "tokens_total": 629226,
- "languages_total": 867,
+ "tokens_total": 630435,
+ "languages_total": 869,
"tokens": {
"ABAP": {
"*/**": 1,
@@ -49935,7 +49941,7 @@
},
"PHP": {
"<": 11,
- "php": 12,
+ "php": 14,
"namespace": 28,
"Symfony": 24,
"Component": 24,
@@ -50659,6 +50665,19 @@
"base_url": 1,
"php_filter_info": 1,
"filters": 2,
+ "SHEBANG#!php": 4,
+ ">": 1,
+ "aMenuLinks": 1,
+ "Array": 13,
+ "Blog": 1,
+ "SITE_DIR": 4,
+ "Photos": 1,
+ "photo": 1,
+ "About": 1,
+ "me": 1,
+ "about": 1,
+ "Contact": 1,
+ "contacts": 1,
"Field": 9,
"FormField": 3,
"ArrayAccess": 1,
@@ -50953,7 +50972,6 @@
"isUnique": 1,
"is_bool": 1,
"sql": 1,
- "SHEBANG#!php": 3,
"echo": 2,
"Yii": 3,
"console": 3,
@@ -67048,9 +67066,9 @@
"return": 1
},
"XML": {
- "": 11,
- "version=": 17,
- "encoding=": 7,
+ "": 12,
+ "version=": 21,
+ "encoding=": 8,
"": 7,
"ToolsVersion=": 6,
"DefaultTargets=": 5,
@@ -67127,6 +67145,94 @@
"": 10,
"": 5,
"": 7,
+ "standalone=": 1,
+ "": 1,
+ "4": 1,
+ "0": 2,
+ "": 1,
+ "storage_type_id=": 1,
+ "": 14,
+ "moduleId=": 14,
+ "": 2,
+ "id=": 141,
+ "buildSystemId=": 2,
+ "name=": 270,
+ "": 2,
+ "": 2,
+ "": 12,
+ "point=": 12,
+ "": 2,
+ "": 7,
+ "": 2,
+ "artifactName=": 2,
+ "buildArtefactType=": 2,
+ "buildProperties=": 2,
+ "cleanCommand=": 2,
+ "description=": 4,
+ "cdt": 2,
+ "managedbuild": 2,
+ "config": 2,
+ "gnu": 2,
+ "exe": 2,
+ "debug": 1,
+ "1803931088": 1,
+ "parent=": 2,
+ "": 2,
+ "resourcePath=": 2,
+ "": 2,
+ "superClass=": 42,
+ "": 2,
+ "": 2,
+ "buildPath=": 2,
+ "keepEnvironmentInBuildfile=": 2,
+ "managedBuildOn=": 2,
+ "": 12,
+ "": 4,
+ "": 8,
+ "": 8,
+ "defaultValue=": 2,
+ "": 4,
+ "kind=": 6,
+ "paths=": 4,
+ "": 2,
+ "": 2,
+ "": 2,
+ "": 2,
+ "": 2,
+ "flags=": 2,
+ "": 2,
+ "": 2,
+ "": 2,
+ "release": 1,
+ "32754498": 1,
+ "": 2,
+ "projectType=": 1,
+ "": 5,
+ "enabled=": 125,
+ "problemReportingEnabled=": 5,
+ "selectedProfileId=": 5,
+ "": 40,
+ "": 40,
+ "": 40,
+ "filePath=": 40,
+ "": 80,
+ "": 40,
+ "": 40,
+ "": 40,
+ "arguments=": 40,
+ "command=": 40,
+ "useDefault=": 40,
+ "": 40,
+ "": 40,
+ "": 4,
+ "instanceId=": 4,
+ "": 4,
+ "": 1,
"": 2,
"": 2,
"cfa7a11": 1,
@@ -67174,8 +67280,6 @@
"FSharp": 1,
"": 1,
"": 1,
- "": 1,
- "name=": 227,
"xmlns": 2,
"ea=": 2,
"": 4,
@@ -67230,14 +67334,12 @@
"application": 2,
"": 1,
"": 1,
- "value=": 1,
"": 1,
"": 1,
"": 1,
"": 1,
"": 2,
"visibility=": 2,
- "description=": 2,
"": 1,
"": 1,
"": 4,
@@ -69756,7 +69858,7 @@
"Ox": 1006,
"Oxygene": 157,
"PAWN": 3263,
- "PHP": 20724,
+ "PHP": 20754,
"Pan": 130,
"Parrot Assembly": 6,
"Parrot Internal Representation": 5,
@@ -69822,7 +69924,7 @@
"Visual Basic": 581,
"Volt": 388,
"XC": 24,
- "XML": 7057,
+ "XML": 8236,
"XProc": 22,
"XQuery": 801,
"XSLT": 44,
@@ -69956,7 +70058,7 @@
"Ox": 3,
"Oxygene": 1,
"PAWN": 1,
- "PHP": 9,
+ "PHP": 10,
"Pan": 1,
"Parrot Assembly": 1,
"Parrot Internal Representation": 1,
@@ -70022,7 +70124,7 @@
"Visual Basic": 3,
"Volt": 1,
"XC": 1,
- "XML": 13,
+ "XML": 14,
"XProc": 1,
"XQuery": 1,
"XSLT": 1,
@@ -70035,5 +70137,5 @@
"fish": 3,
"wisp": 1
},
- "md5": "cedc5d3fde7e7b87467bdf820d674b95"
+ "md5": "1edee1d2c454fb877027ae980cd163ef"
}
\ No newline at end of file
diff --git a/samples/PHP/filenames/.php b/samples/PHP/filenames/.php
new file mode 100755
index 00000000..be170195
--- /dev/null
+++ b/samples/PHP/filenames/.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+
+$aMenuLinks = Array(
+ Array(
+ "Blog",
+ SITE_DIR,
+ Array(),
+ Array(),
+ ""
+ ),
+ Array(
+ "Photos",
+ SITE_DIR."photo/",
+ Array(),
+ Array(),
+ ""
+ ),
+ Array(
+ "About me",
+ SITE_DIR."about.php",
+ Array(),
+ Array(),
+ ""
+ ),
+ Array(
+ "Contact",
+ SITE_DIR."contacts.php",
+ Array(),
+ Array(),
+ ""
+ ),
+
+);
+?>
diff --git a/samples/XML/filenames/.cproject b/samples/XML/filenames/.cproject
new file mode 100755
index 00000000..5fbff7b7
--- /dev/null
+++ b/samples/XML/filenames/.cproject
@@ -0,0 +1,542 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/test_language.rb b/test/test_language.rb
index 10c5f9a2..fa92f38c 100644
--- a/test/test_language.rb
+++ b/test/test_language.rb
@@ -249,8 +249,7 @@ class TestLanguage < Test::Unit::TestCase
assert_equal Language['Nginx'], Language.find_by_filename('nginx.conf').first
assert_equal ['C', 'C++', 'Objective-C'], Language.find_by_filename('foo.h').map(&:name).sort
assert_equal [], Language.find_by_filename('rb')
- assert_equal [], Language.find_by_filename('.rb')
- assert_equal [], Language.find_by_filename('.nkt')
+ assert_equal [], Language.find_by_filename('.null')
assert_equal [Language['Shell']], Language.find_by_filename('.bashrc')
assert_equal [Language['Shell']], Language.find_by_filename('bash_profile')
assert_equal [Language['Shell']], Language.find_by_filename('.zshrc')