mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Compare commits
	
		
			30 Commits
		
	
	
		
			v5.3.0
			...
			vmg/compil
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5812f89f66 | ||
| 
						 | 
					e4b9430024 | ||
| 
						 | 
					a76805e40d | ||
| 
						 | 
					8d27845f8c | ||
| 
						 | 
					9a8ab45b6f | ||
| 
						 | 
					e335d48625 | ||
| 
						 | 
					4f46155c05 | ||
| 
						 | 
					38901d51d2 | ||
| 
						 | 
					ded0dc74e0 | ||
| 
						 | 
					c5d1bb5370 | ||
| 
						 | 
					c8ca48856b | ||
| 
						 | 
					7be6fb0138 | ||
| 
						 | 
					8c516655bc | ||
| 
						 | 
					9dceffce2f | ||
| 
						 | 
					33be70eb28 | ||
| 
						 | 
					9c4dc3047c | ||
| 
						 | 
					d8e5f3c965 | ||
| 
						 | 
					71bf640a47 | ||
| 
						 | 
					c9b3d19c6f | ||
| 
						 | 
					0f4955e5d5 | ||
| 
						 | 
					d968b0e9ee | ||
| 
						 | 
					1f5ed3b3fe | ||
| 
						 | 
					297be948d1 | ||
| 
						 | 
					b4492e7205 | ||
| 
						 | 
					c05bc99004 | ||
| 
						 | 
					99eaf5faf9 | ||
| 
						 | 
					21babbceb1 | ||
| 
						 | 
					15885701cd | ||
| 
						 | 
					9b942086f7 | ||
| 
						 | 
					93cd47822f | 
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -8,3 +8,6 @@ lib/linguist/samples.json
 | 
				
			|||||||
/node_modules
 | 
					/node_modules
 | 
				
			||||||
test/fixtures/ace_modes.json
 | 
					test/fixtures/ace_modes.json
 | 
				
			||||||
/vendor/gems/
 | 
					/vendor/gems/
 | 
				
			||||||
 | 
					/tmp
 | 
				
			||||||
 | 
					*.bundle
 | 
				
			||||||
 | 
					*.so
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							@@ -169,9 +169,6 @@
 | 
				
			|||||||
[submodule "vendor/grammars/Agda.tmbundle"]
 | 
					[submodule "vendor/grammars/Agda.tmbundle"]
 | 
				
			||||||
	path = vendor/grammars/Agda.tmbundle
 | 
						path = vendor/grammars/Agda.tmbundle
 | 
				
			||||||
	url = https://github.com/mokus0/Agda.tmbundle
 | 
						url = https://github.com/mokus0/Agda.tmbundle
 | 
				
			||||||
[submodule "vendor/grammars/Julia.tmbundle"]
 | 
					 | 
				
			||||||
	path = vendor/grammars/Julia.tmbundle
 | 
					 | 
				
			||||||
	url = https://github.com/JuliaEditorSupport/Julia.tmbundle
 | 
					 | 
				
			||||||
[submodule "vendor/grammars/ooc.tmbundle"]
 | 
					[submodule "vendor/grammars/ooc.tmbundle"]
 | 
				
			||||||
	path = vendor/grammars/ooc.tmbundle
 | 
						path = vendor/grammars/ooc.tmbundle
 | 
				
			||||||
	url = https://github.com/nilium/ooc.tmbundle
 | 
						url = https://github.com/nilium/ooc.tmbundle
 | 
				
			||||||
@@ -442,9 +439,6 @@
 | 
				
			|||||||
[submodule "vendor/grammars/sublime-golo"]
 | 
					[submodule "vendor/grammars/sublime-golo"]
 | 
				
			||||||
	path = vendor/grammars/sublime-golo
 | 
						path = vendor/grammars/sublime-golo
 | 
				
			||||||
	url = https://github.com/TypeUnsafe/sublime-golo
 | 
						url = https://github.com/TypeUnsafe/sublime-golo
 | 
				
			||||||
[submodule "vendor/grammars/JSyntax"]
 | 
					 | 
				
			||||||
	path = vendor/grammars/JSyntax
 | 
					 | 
				
			||||||
	url = https://github.com/bcj/JSyntax
 | 
					 | 
				
			||||||
[submodule "vendor/grammars/TXL"]
 | 
					[submodule "vendor/grammars/TXL"]
 | 
				
			||||||
	path = vendor/grammars/TXL
 | 
						path = vendor/grammars/TXL
 | 
				
			||||||
	url = https://github.com/MikeHoffert/Sublime-Text-TXL-syntax
 | 
						url = https://github.com/MikeHoffert/Sublime-Text-TXL-syntax
 | 
				
			||||||
@@ -871,6 +865,9 @@
 | 
				
			|||||||
[submodule "vendor/grammars/language-ballerina"]
 | 
					[submodule "vendor/grammars/language-ballerina"]
 | 
				
			||||||
	path = vendor/grammars/language-ballerina
 | 
						path = vendor/grammars/language-ballerina
 | 
				
			||||||
	url = https://github.com/ballerinalang/plugin-vscode
 | 
						url = https://github.com/ballerinalang/plugin-vscode
 | 
				
			||||||
 | 
					[submodule "vendor/grammars/language-yara"]
 | 
				
			||||||
 | 
						path = vendor/grammars/language-yara
 | 
				
			||||||
 | 
						url = https://github.com/blacktop/language-yara
 | 
				
			||||||
[submodule "vendor/grammars/language-ruby"]
 | 
					[submodule "vendor/grammars/language-ruby"]
 | 
				
			||||||
	path = vendor/grammars/language-ruby
 | 
						path = vendor/grammars/language-ruby
 | 
				
			||||||
	url = https://github.com/atom/language-ruby
 | 
						url = https://github.com/atom/language-ruby
 | 
				
			||||||
@@ -883,3 +880,18 @@
 | 
				
			|||||||
[submodule "vendor/grammars/wdl-sublime-syntax-highlighter"]
 | 
					[submodule "vendor/grammars/wdl-sublime-syntax-highlighter"]
 | 
				
			||||||
	path = vendor/grammars/wdl-sublime-syntax-highlighter
 | 
						path = vendor/grammars/wdl-sublime-syntax-highlighter
 | 
				
			||||||
	url = https://github.com/broadinstitute/wdl-sublime-syntax-highlighter
 | 
						url = https://github.com/broadinstitute/wdl-sublime-syntax-highlighter
 | 
				
			||||||
 | 
					[submodule "vendor/grammars/atom-language-julia"]
 | 
				
			||||||
 | 
						path = vendor/grammars/atom-language-julia
 | 
				
			||||||
 | 
						url = https://github.com/JuliaEditorSupport/atom-language-julia
 | 
				
			||||||
 | 
					[submodule "vendor/grammars/language-cwl"]
 | 
				
			||||||
 | 
						path = vendor/grammars/language-cwl
 | 
				
			||||||
 | 
						url = https://github.com/manabuishii/language-cwl
 | 
				
			||||||
 | 
					[submodule "vendor/grammars/Syntax-highlighting-for-PostCSS"]
 | 
				
			||||||
 | 
						path = vendor/grammars/Syntax-highlighting-for-PostCSS
 | 
				
			||||||
 | 
						url = https://github.com/hudochenkov/Syntax-highlighting-for-PostCSS
 | 
				
			||||||
 | 
					[submodule "vendor/grammars/javadoc.tmbundle"]
 | 
				
			||||||
 | 
						path = vendor/grammars/javadoc.tmbundle
 | 
				
			||||||
 | 
						url = https://github.com/textmate/javadoc.tmbundle
 | 
				
			||||||
 | 
					[submodule "vendor/grammars/JSyntax"]
 | 
				
			||||||
 | 
						path = vendor/grammars/JSyntax
 | 
				
			||||||
 | 
						url = https://github.com/tikkanz/JSyntax
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,10 +19,6 @@ rvm:
 | 
				
			|||||||
  - 2.3.3
 | 
					  - 2.3.3
 | 
				
			||||||
  - 2.4.0
 | 
					  - 2.4.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
matrix:
 | 
					 | 
				
			||||||
  allow_failures:
 | 
					 | 
				
			||||||
  - rvm: 2.4.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
notifications:
 | 
					notifications:
 | 
				
			||||||
  disabled: true
 | 
					  disabled: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,6 +93,7 @@ Linguist is maintained with :heart: by:
 | 
				
			|||||||
- **@BenEddy** (GitHub staff)
 | 
					- **@BenEddy** (GitHub staff)
 | 
				
			||||||
- **@Caged** (GitHub staff)
 | 
					- **@Caged** (GitHub staff)
 | 
				
			||||||
- **@grantr** (GitHub staff)
 | 
					- **@grantr** (GitHub staff)
 | 
				
			||||||
 | 
					- **@kivikakk** (GitHub staff)
 | 
				
			||||||
- **@larsbrinkhoff**
 | 
					- **@larsbrinkhoff**
 | 
				
			||||||
- **@lildude** (GitHub staff)
 | 
					- **@lildude** (GitHub staff)
 | 
				
			||||||
- **@pchaigno**
 | 
					- **@pchaigno**
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								Rakefile
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								Rakefile
									
									
									
									
									
								
							@@ -1,6 +1,7 @@
 | 
				
			|||||||
require 'bundler/setup'
 | 
					require 'bundler/setup'
 | 
				
			||||||
require 'rake/clean'
 | 
					require 'rake/clean'
 | 
				
			||||||
require 'rake/testtask'
 | 
					require 'rake/testtask'
 | 
				
			||||||
 | 
					require 'rake/extensiontask'
 | 
				
			||||||
require 'yaml'
 | 
					require 'yaml'
 | 
				
			||||||
require 'yajl'
 | 
					require 'yajl'
 | 
				
			||||||
require 'open-uri'
 | 
					require 'open-uri'
 | 
				
			||||||
@@ -10,8 +11,14 @@ task :default => :test
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Rake::TestTask.new
 | 
					Rake::TestTask.new
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gem_spec = Gem::Specification.load('github-linguist.gemspec')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Rake::ExtensionTask.new('linguist', gem_spec) do |ext|
 | 
				
			||||||
 | 
					  ext.lib_dir = File.join('lib', 'linguist')
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Extend test task to check for samples and fetch latest Ace modes
 | 
					# Extend test task to check for samples and fetch latest Ace modes
 | 
				
			||||||
task :test => [:check_samples, :fetch_ace_modes]
 | 
					task :test => [:compile, :check_samples, :fetch_ace_modes]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
desc "Check that we have samples.json generated"
 | 
					desc "Check that we have samples.json generated"
 | 
				
			||||||
task :check_samples do
 | 
					task :check_samples do
 | 
				
			||||||
@@ -34,12 +41,19 @@ task :fetch_ace_modes do
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
task :samples do
 | 
					task :samples => :compile do
 | 
				
			||||||
  require 'linguist/samples'
 | 
					  require 'linguist/samples'
 | 
				
			||||||
  json = Yajl.dump(Linguist::Samples.data, :pretty => true)
 | 
					  json = Yajl.dump(Linguist::Samples.data, :pretty => true)
 | 
				
			||||||
  File.write 'lib/linguist/samples.json', json
 | 
					  File.write 'lib/linguist/samples.json', json
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					task :flex do
 | 
				
			||||||
 | 
					  if `flex -V` !~ /^flex \d+\.\d+\.\d+/
 | 
				
			||||||
 | 
					    fail "flex not detected"
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  system "cd ext/linguist && flex tokenizer.l"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
task :build_gem => :samples do
 | 
					task :build_gem => :samples do
 | 
				
			||||||
  rm_rf "grammars"
 | 
					  rm_rf "grammars"
 | 
				
			||||||
  sh "script/convert-grammars"
 | 
					  sh "script/convert-grammars"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								ext/linguist/extconf.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ext/linguist/extconf.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					require 'mkmf'
 | 
				
			||||||
 | 
					dir_config('linguist')
 | 
				
			||||||
 | 
					create_makefile('linguist/linguist')
 | 
				
			||||||
							
								
								
									
										2226
									
								
								ext/linguist/lex.linguist_yy.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2226
									
								
								ext/linguist/lex.linguist_yy.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										336
									
								
								ext/linguist/lex.linguist_yy.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										336
									
								
								ext/linguist/lex.linguist_yy.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,336 @@
 | 
				
			|||||||
 | 
					#ifndef linguist_yyHEADER_H
 | 
				
			||||||
 | 
					#define linguist_yyHEADER_H 1
 | 
				
			||||||
 | 
					#define linguist_yyIN_HEADER 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#line 6 "lex.linguist_yy.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define  YY_INT_ALIGNED short int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* A lexical scanner generated by flex */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FLEX_SCANNER
 | 
				
			||||||
 | 
					#define YY_FLEX_MAJOR_VERSION 2
 | 
				
			||||||
 | 
					#define YY_FLEX_MINOR_VERSION 5
 | 
				
			||||||
 | 
					#define YY_FLEX_SUBMINOR_VERSION 35
 | 
				
			||||||
 | 
					#if YY_FLEX_SUBMINOR_VERSION > 0
 | 
				
			||||||
 | 
					#define FLEX_BETA
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* First, we deal with  platform-specific or compiler-specific issues. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* begin standard C headers. */
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* end standard C headers. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* flex integer type definitions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef FLEXINT_H
 | 
				
			||||||
 | 
					#define FLEXINT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
 | 
				
			||||||
 | 
					 * if you want the limit (max/min) macros for int types. 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef __STDC_LIMIT_MACROS
 | 
				
			||||||
 | 
					#define __STDC_LIMIT_MACROS 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					typedef int8_t flex_int8_t;
 | 
				
			||||||
 | 
					typedef uint8_t flex_uint8_t;
 | 
				
			||||||
 | 
					typedef int16_t flex_int16_t;
 | 
				
			||||||
 | 
					typedef uint16_t flex_uint16_t;
 | 
				
			||||||
 | 
					typedef int32_t flex_int32_t;
 | 
				
			||||||
 | 
					typedef uint32_t flex_uint32_t;
 | 
				
			||||||
 | 
					typedef uint64_t flex_uint64_t;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					typedef signed char flex_int8_t;
 | 
				
			||||||
 | 
					typedef short int flex_int16_t;
 | 
				
			||||||
 | 
					typedef int flex_int32_t;
 | 
				
			||||||
 | 
					typedef unsigned char flex_uint8_t; 
 | 
				
			||||||
 | 
					typedef unsigned short int flex_uint16_t;
 | 
				
			||||||
 | 
					typedef unsigned int flex_uint32_t;
 | 
				
			||||||
 | 
					#endif /* ! C99 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Limits of integral types. */
 | 
				
			||||||
 | 
					#ifndef INT8_MIN
 | 
				
			||||||
 | 
					#define INT8_MIN               (-128)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef INT16_MIN
 | 
				
			||||||
 | 
					#define INT16_MIN              (-32767-1)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef INT32_MIN
 | 
				
			||||||
 | 
					#define INT32_MIN              (-2147483647-1)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef INT8_MAX
 | 
				
			||||||
 | 
					#define INT8_MAX               (127)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef INT16_MAX
 | 
				
			||||||
 | 
					#define INT16_MAX              (32767)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef INT32_MAX
 | 
				
			||||||
 | 
					#define INT32_MAX              (2147483647)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef UINT8_MAX
 | 
				
			||||||
 | 
					#define UINT8_MAX              (255U)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef UINT16_MAX
 | 
				
			||||||
 | 
					#define UINT16_MAX             (65535U)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef UINT32_MAX
 | 
				
			||||||
 | 
					#define UINT32_MAX             (4294967295U)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* ! FLEXINT_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The "const" storage-class-modifier is valid. */
 | 
				
			||||||
 | 
					#define YY_USE_CONST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else	/* ! __cplusplus */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* C99 requires __STDC__ to be defined as 1. */
 | 
				
			||||||
 | 
					#if defined (__STDC__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define YY_USE_CONST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif	/* defined (__STDC__) */
 | 
				
			||||||
 | 
					#endif	/* ! __cplusplus */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef YY_USE_CONST
 | 
				
			||||||
 | 
					#define yyconst const
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define yyconst
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* An opaque pointer. */
 | 
				
			||||||
 | 
					#ifndef YY_TYPEDEF_YY_SCANNER_T
 | 
				
			||||||
 | 
					#define YY_TYPEDEF_YY_SCANNER_T
 | 
				
			||||||
 | 
					typedef void* yyscan_t;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* For convenience, these vars (plus the bison vars far below)
 | 
				
			||||||
 | 
					   are macros in the reentrant scanner. */
 | 
				
			||||||
 | 
					#define yyin yyg->yyin_r
 | 
				
			||||||
 | 
					#define yyout yyg->yyout_r
 | 
				
			||||||
 | 
					#define yyextra yyg->yyextra_r
 | 
				
			||||||
 | 
					#define yyleng yyg->yyleng_r
 | 
				
			||||||
 | 
					#define yytext yyg->yytext_r
 | 
				
			||||||
 | 
					#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
 | 
				
			||||||
 | 
					#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
 | 
				
			||||||
 | 
					#define yy_flex_debug yyg->yy_flex_debug_r
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Size of default input buffer. */
 | 
				
			||||||
 | 
					#ifndef YY_BUF_SIZE
 | 
				
			||||||
 | 
					#define YY_BUF_SIZE 16384
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef YY_TYPEDEF_YY_BUFFER_STATE
 | 
				
			||||||
 | 
					#define YY_TYPEDEF_YY_BUFFER_STATE
 | 
				
			||||||
 | 
					typedef struct yy_buffer_state *YY_BUFFER_STATE;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef YY_TYPEDEF_YY_SIZE_T
 | 
				
			||||||
 | 
					#define YY_TYPEDEF_YY_SIZE_T
 | 
				
			||||||
 | 
					typedef size_t yy_size_t;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef YY_STRUCT_YY_BUFFER_STATE
 | 
				
			||||||
 | 
					#define YY_STRUCT_YY_BUFFER_STATE
 | 
				
			||||||
 | 
					struct yy_buffer_state
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						FILE *yy_input_file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *yy_ch_buf;		/* input buffer */
 | 
				
			||||||
 | 
						char *yy_buf_pos;		/* current position in input buffer */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Size of input buffer in bytes, not including room for EOB
 | 
				
			||||||
 | 
						 * characters.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						yy_size_t yy_buf_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Number of characters read into yy_ch_buf, not including EOB
 | 
				
			||||||
 | 
						 * characters.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						yy_size_t yy_n_chars;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Whether we "own" the buffer - i.e., we know we created it,
 | 
				
			||||||
 | 
						 * and can realloc() it to grow it, and should free() it to
 | 
				
			||||||
 | 
						 * delete it.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						int yy_is_our_buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Whether this is an "interactive" input source; if so, and
 | 
				
			||||||
 | 
						 * if we're using stdio for input, then we want to use getc()
 | 
				
			||||||
 | 
						 * instead of fread(), to make sure we stop fetching input after
 | 
				
			||||||
 | 
						 * each newline.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						int yy_is_interactive;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Whether we're considered to be at the beginning of a line.
 | 
				
			||||||
 | 
						 * If so, '^' rules will be active on the next match, otherwise
 | 
				
			||||||
 | 
						 * not.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						int yy_at_bol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int yy_bs_lineno; /**< The line count. */
 | 
				
			||||||
 | 
					    int yy_bs_column; /**< The column count. */
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
						/* Whether to try to fill the input buffer when we reach the
 | 
				
			||||||
 | 
						 * end of it.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						int yy_fill_buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int yy_buffer_status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					#endif /* !YY_STRUCT_YY_BUFFER_STATE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void linguist_yyrestart (FILE *input_file ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					void linguist_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					YY_BUFFER_STATE linguist_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					void linguist_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					void linguist_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					void linguist_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					void linguist_yypop_buffer_state (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					YY_BUFFER_STATE linguist_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					YY_BUFFER_STATE linguist_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					YY_BUFFER_STATE linguist_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *linguist_yyalloc (yy_size_t ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					void *linguist_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					void linguist_yyfree (void * ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Begin user sect3 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define yytext_ptr yytext_r
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef YY_HEADER_EXPORT_START_CONDITIONS
 | 
				
			||||||
 | 
					#define INITIAL 0
 | 
				
			||||||
 | 
					#define sgml 1
 | 
				
			||||||
 | 
					#define c_comment 2
 | 
				
			||||||
 | 
					#define xml_comment 3
 | 
				
			||||||
 | 
					#define haskell_comment 4
 | 
				
			||||||
 | 
					#define ocaml_comment 5
 | 
				
			||||||
 | 
					#define python_dcomment 6
 | 
				
			||||||
 | 
					#define python_scomment 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef YY_NO_UNISTD_H
 | 
				
			||||||
 | 
					/* Special case for "unistd.h", since it is non-ANSI. We include it way
 | 
				
			||||||
 | 
					 * down here because we want the user's section 1 to have been scanned first.
 | 
				
			||||||
 | 
					 * The user has a chance to override it with an option.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define YY_EXTRA_TYPE struct tokenizer_extra *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int linguist_yylex_init (yyscan_t* scanner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int linguist_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Accessor methods to globals.
 | 
				
			||||||
 | 
					   These are made visible to non-reentrant scanners for convenience. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int linguist_yylex_destroy (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int linguist_yyget_debug (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void linguist_yyset_debug (int debug_flag ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					YY_EXTRA_TYPE linguist_yyget_extra (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void linguist_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FILE *linguist_yyget_in (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void linguist_yyset_in  (FILE * in_str ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FILE *linguist_yyget_out (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void linguist_yyset_out  (FILE * out_str ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					yy_size_t linguist_yyget_leng (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *linguist_yyget_text (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int linguist_yyget_lineno (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void linguist_yyset_lineno (int line_number ,yyscan_t yyscanner );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Macros after this point can all be overridden by user definitions in
 | 
				
			||||||
 | 
					 * section 1.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef YY_SKIP_YYWRAP
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" int linguist_yywrap (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					extern int linguist_yywrap (yyscan_t yyscanner );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef yytext_ptr
 | 
				
			||||||
 | 
					static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef YY_NEED_STRLEN
 | 
				
			||||||
 | 
					static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef YY_NO_INPUT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Amount of stuff to slurp up with each read. */
 | 
				
			||||||
 | 
					#ifndef YY_READ_BUF_SIZE
 | 
				
			||||||
 | 
					#define YY_READ_BUF_SIZE 8192
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Number of entries by which start-condition stack grows. */
 | 
				
			||||||
 | 
					#ifndef YY_START_STACK_INCR
 | 
				
			||||||
 | 
					#define YY_START_STACK_INCR 25
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Default declaration of generated scanner - a define so the user can
 | 
				
			||||||
 | 
					 * easily add parameters.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef YY_DECL
 | 
				
			||||||
 | 
					#define YY_DECL_IS_OURS 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int linguist_yylex (yyscan_t yyscanner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define YY_DECL int linguist_yylex (yyscan_t yyscanner)
 | 
				
			||||||
 | 
					#endif /* !YY_DECL */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* yy_get_previous_state - get the state just before the EOB char was reached */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef YY_NEW_FILE
 | 
				
			||||||
 | 
					#undef YY_FLUSH_BUFFER
 | 
				
			||||||
 | 
					#undef yy_set_bol
 | 
				
			||||||
 | 
					#undef yy_new_buffer
 | 
				
			||||||
 | 
					#undef yy_set_interactive
 | 
				
			||||||
 | 
					#undef YY_DO_BEFORE_ACTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef YY_DECL_IS_OURS
 | 
				
			||||||
 | 
					#undef YY_DECL_IS_OURS
 | 
				
			||||||
 | 
					#undef YY_DECL
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#line 118 "tokenizer.l"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#line 335 "lex.linguist_yy.h"
 | 
				
			||||||
 | 
					#undef linguist_yyIN_HEADER
 | 
				
			||||||
 | 
					#endif /* linguist_yyHEADER_H */
 | 
				
			||||||
							
								
								
									
										75
									
								
								ext/linguist/linguist.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								ext/linguist/linguist.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					#include "ruby.h"
 | 
				
			||||||
 | 
					#include "linguist.h"
 | 
				
			||||||
 | 
					#include "lex.linguist_yy.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Anything longer is unlikely to be useful.
 | 
				
			||||||
 | 
					#define MAX_TOKEN_LEN 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int linguist_yywrap(yyscan_t yyscanner) {
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static VALUE rb_tokenizer_extract_tokens(VALUE self, VALUE rb_data) {
 | 
				
			||||||
 | 
						YY_BUFFER_STATE buf;
 | 
				
			||||||
 | 
						yyscan_t scanner;
 | 
				
			||||||
 | 
						struct tokenizer_extra extra;
 | 
				
			||||||
 | 
						VALUE ary, s;
 | 
				
			||||||
 | 
						long len;
 | 
				
			||||||
 | 
						int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Check_Type(rb_data, T_STRING);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = RSTRING_LEN(rb_data);
 | 
				
			||||||
 | 
						if (len > 100000)
 | 
				
			||||||
 | 
							len = 100000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						linguist_yylex_init_extra(&extra, &scanner);
 | 
				
			||||||
 | 
						buf = linguist_yy_scan_bytes(RSTRING_PTR(rb_data), (int) len, scanner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ary = rb_ary_new();
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							extra.type = NO_ACTION;
 | 
				
			||||||
 | 
							extra.token = NULL;
 | 
				
			||||||
 | 
							r = linguist_yylex(scanner);
 | 
				
			||||||
 | 
							switch (extra.type) {
 | 
				
			||||||
 | 
							case NO_ACTION:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case REGULAR_TOKEN:
 | 
				
			||||||
 | 
								len = strlen(extra.token);
 | 
				
			||||||
 | 
								if (len <= MAX_TOKEN_LEN)
 | 
				
			||||||
 | 
									rb_ary_push(ary, rb_str_new(extra.token, len));
 | 
				
			||||||
 | 
								free(extra.token);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SHEBANG_TOKEN:
 | 
				
			||||||
 | 
								len = strlen(extra.token);
 | 
				
			||||||
 | 
								if (len <= MAX_TOKEN_LEN) {
 | 
				
			||||||
 | 
									s = rb_str_new2("SHEBANG#!");
 | 
				
			||||||
 | 
									rb_str_cat(s, extra.token, len);
 | 
				
			||||||
 | 
									rb_ary_push(ary, s);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								free(extra.token);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SGML_TOKEN:
 | 
				
			||||||
 | 
								len = strlen(extra.token);
 | 
				
			||||||
 | 
								if (len <= MAX_TOKEN_LEN) {
 | 
				
			||||||
 | 
									s = rb_str_new(extra.token, len);
 | 
				
			||||||
 | 
									rb_str_cat2(s, ">");
 | 
				
			||||||
 | 
									rb_ary_push(ary, s);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								free(extra.token);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} while (r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						linguist_yy_delete_buffer(buf, scanner);
 | 
				
			||||||
 | 
						linguist_yylex_destroy(scanner);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ary;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute__((visibility("default"))) void Init_linguist() {
 | 
				
			||||||
 | 
						VALUE rb_mLinguist = rb_define_module("Linguist");
 | 
				
			||||||
 | 
						VALUE rb_cTokenizer = rb_define_class_under(rb_mLinguist, "Tokenizer", rb_cObject);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rb_define_method(rb_cTokenizer, "extract_tokens", rb_tokenizer_extract_tokens, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								ext/linguist/linguist.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								ext/linguist/linguist.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					enum tokenizer_type {
 | 
				
			||||||
 | 
					  NO_ACTION,
 | 
				
			||||||
 | 
					  REGULAR_TOKEN,
 | 
				
			||||||
 | 
					  SHEBANG_TOKEN,
 | 
				
			||||||
 | 
					  SGML_TOKEN,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct tokenizer_extra {
 | 
				
			||||||
 | 
					  char *token;
 | 
				
			||||||
 | 
					  enum tokenizer_type type;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										119
									
								
								ext/linguist/tokenizer.l
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								ext/linguist/tokenizer.l
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
				
			|||||||
 | 
					%{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "linguist.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define feed_token(tok, typ) do { \
 | 
				
			||||||
 | 
					    yyextra->token = (tok); \
 | 
				
			||||||
 | 
					    yyextra->type = (typ); \
 | 
				
			||||||
 | 
					  } while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define eat_until_eol() do { \
 | 
				
			||||||
 | 
					    int c; \
 | 
				
			||||||
 | 
					    while ((c = input(yyscanner)) != '\n' && c != EOF && c); \
 | 
				
			||||||
 | 
					    if (c == EOF || !c) \
 | 
				
			||||||
 | 
					      return 0; \
 | 
				
			||||||
 | 
					  } while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define eat_until_unescaped(q) do { \
 | 
				
			||||||
 | 
					    int c; \
 | 
				
			||||||
 | 
					    while ((c = input(yyscanner)) != EOF && c) { \
 | 
				
			||||||
 | 
					      if (c == '\n') \
 | 
				
			||||||
 | 
					        break; \
 | 
				
			||||||
 | 
					      if (c == '\\') { \
 | 
				
			||||||
 | 
					        c = input(yyscanner); \
 | 
				
			||||||
 | 
					        if (c == EOF || !c) \
 | 
				
			||||||
 | 
					          return 0; \
 | 
				
			||||||
 | 
					      } else if (c == q) \
 | 
				
			||||||
 | 
					        break; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					    if (c == EOF || !c) \
 | 
				
			||||||
 | 
					      return 0; \
 | 
				
			||||||
 | 
					  } while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%option never-interactive yywrap reentrant nounput warn nodefault header-file="lex.linguist_yy.h" extra-type="struct tokenizer_extra *" prefix="linguist_yy"
 | 
				
			||||||
 | 
					%x sgml c_comment xml_comment haskell_comment ocaml_comment python_dcomment python_scomment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					^#![ \t]*([[:alnum:]_\/]*\/)?env([ \t]+([^ \t=]*=[^ \t]*))*[ \t]+[[:alpha:]_]+ {
 | 
				
			||||||
 | 
					    const char *off = strrchr(yytext, ' ');
 | 
				
			||||||
 | 
					    if (!off)
 | 
				
			||||||
 | 
					      off = yytext;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      ++off;
 | 
				
			||||||
 | 
					    feed_token(strdup(off), SHEBANG_TOKEN);
 | 
				
			||||||
 | 
					    eat_until_eol();
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					^#![ \t]*[[:alpha:]_\/]+ {
 | 
				
			||||||
 | 
					    const char *off = strrchr(yytext, '/');
 | 
				
			||||||
 | 
					    if (!off)
 | 
				
			||||||
 | 
					      off = yytext;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      ++off;
 | 
				
			||||||
 | 
					    if (strcmp(off, "env") == 0) {
 | 
				
			||||||
 | 
					      eat_until_eol();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      feed_token(strdup(off), SHEBANG_TOKEN);
 | 
				
			||||||
 | 
					      eat_until_eol();
 | 
				
			||||||
 | 
					      return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					^[ \t]*(\/\/|--|\#|%|\")" ".*   { /* nothing */ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"/*"                              { BEGIN(c_comment); }
 | 
				
			||||||
 | 
					  /* See below for xml_comment start. */
 | 
				
			||||||
 | 
					"{-"                              { BEGIN(haskell_comment); }
 | 
				
			||||||
 | 
					"(*"                              { BEGIN(ocaml_comment); }
 | 
				
			||||||
 | 
					"\"\"\""                          { BEGIN(python_dcomment); }
 | 
				
			||||||
 | 
					"'''"                             { BEGIN(python_scomment); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<c_comment,xml_comment,haskell_comment,ocaml_comment,python_dcomment,python_scomment>.|\n { /* nothing */ }
 | 
				
			||||||
 | 
					<c_comment>"*/"                   { BEGIN(INITIAL); }
 | 
				
			||||||
 | 
					<xml_comment>"-->"                { BEGIN(INITIAL); }
 | 
				
			||||||
 | 
					<haskell_comment>"-}"             { BEGIN(INITIAL); }
 | 
				
			||||||
 | 
					<ocaml_comment>"*)"               { BEGIN(INITIAL); }
 | 
				
			||||||
 | 
					<python_dcomment>"\"\"\""         { BEGIN(INITIAL); }
 | 
				
			||||||
 | 
					<python_scomment>"'''"            { BEGIN(INITIAL); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					\"\"|''                           { /* nothing */ }
 | 
				
			||||||
 | 
					\"                                { eat_until_unescaped('"'); }
 | 
				
			||||||
 | 
					'                                 { eat_until_unescaped('\''); }
 | 
				
			||||||
 | 
					(0x[0-9a-fA-F]([0-9a-fA-F]|\.)*|[0-9]([0-9]|\.)*)([uU][lL]{0,2}|([eE][-+][0-9]*)?[fFlL]*) { /* nothing */ }
 | 
				
			||||||
 | 
					\<[[:alnum:]_!./?-]+              {
 | 
				
			||||||
 | 
					    if (strcmp(yytext, "<!--") == 0) {
 | 
				
			||||||
 | 
					     BEGIN(xml_comment);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      feed_token(strdup(yytext), SGML_TOKEN);
 | 
				
			||||||
 | 
					      BEGIN(sgml);
 | 
				
			||||||
 | 
					      return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					<sgml>[[:alnum:]_]+=\"            { feed_token(strndup(yytext, strlen(yytext) - 1), REGULAR_TOKEN); eat_until_unescaped('"'); return 1; }
 | 
				
			||||||
 | 
					<sgml>[[:alnum:]_]+='             { feed_token(strndup(yytext, strlen(yytext) - 1), REGULAR_TOKEN); eat_until_unescaped('\''); return 1; }
 | 
				
			||||||
 | 
					<sgml>[[:alnum:]_]+=[[:alnum:]_]* { feed_token(strdup(yytext), REGULAR_TOKEN); *(strchr(yyextra->token, '=') + 1) = 0; return 1; }
 | 
				
			||||||
 | 
					<sgml>[[:alnum:]_]+               { feed_token(strdup(yytext), REGULAR_TOKEN); return 1; }
 | 
				
			||||||
 | 
					<sgml>\>                          { BEGIN(INITIAL); }
 | 
				
			||||||
 | 
					<sgml>.|\n                        { /* nothing */ }
 | 
				
			||||||
 | 
					;|\{|\}|\(|\)|\[|\]               { feed_token(strdup(yytext), REGULAR_TOKEN); return 1; }
 | 
				
			||||||
 | 
					[[:alnum:]_.@#/*]+                {
 | 
				
			||||||
 | 
					    if (strncmp(yytext, "/*", 2) == 0) {
 | 
				
			||||||
 | 
					      if (strlen(yytext) >= 4 && strcmp(yytext + strlen(yytext) - 2, "*/") == 0) {
 | 
				
			||||||
 | 
					        /* nothing */
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        BEGIN(c_comment);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      feed_token(strdup(yytext), REGULAR_TOKEN);
 | 
				
			||||||
 | 
					      return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					\<\<?|\+|\-|\*|\/|%|&&?|\|\|?     { feed_token(strdup(yytext), REGULAR_TOKEN); return 1; }
 | 
				
			||||||
 | 
					.|\n                              { /* nothing */ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -10,8 +10,9 @@ Gem::Specification.new do |s|
 | 
				
			|||||||
  s.homepage = "https://github.com/github/linguist"
 | 
					  s.homepage = "https://github.com/github/linguist"
 | 
				
			||||||
  s.license  = "MIT"
 | 
					  s.license  = "MIT"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  s.files = Dir['lib/**/*'] + Dir['grammars/*'] + ['LICENSE']
 | 
					  s.files = Dir['lib/**/*'] + Dir['ext/**/*'] + Dir['grammars/*'] + ['LICENSE']
 | 
				
			||||||
  s.executables = ['linguist', 'git-linguist']
 | 
					  s.executables = ['linguist', 'git-linguist']
 | 
				
			||||||
 | 
					  s.extensions = ['ext/linguist/extconf.rb']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  s.add_dependency 'charlock_holmes', '~> 0.7.5'
 | 
					  s.add_dependency 'charlock_holmes', '~> 0.7.5'
 | 
				
			||||||
  s.add_dependency 'escape_utils',    '~> 1.1.0'
 | 
					  s.add_dependency 'escape_utils',    '~> 1.1.0'
 | 
				
			||||||
@@ -19,6 +20,7 @@ Gem::Specification.new do |s|
 | 
				
			|||||||
  s.add_dependency 'rugged',          '>= 0.25.1'
 | 
					  s.add_dependency 'rugged',          '>= 0.25.1'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  s.add_development_dependency 'minitest', '>= 5.0'
 | 
					  s.add_development_dependency 'minitest', '>= 5.0'
 | 
				
			||||||
 | 
					  s.add_development_dependency 'rake-compiler', '~> 0.9'
 | 
				
			||||||
  s.add_development_dependency 'mocha'
 | 
					  s.add_development_dependency 'mocha'
 | 
				
			||||||
  s.add_development_dependency 'plist', '~>3.1'
 | 
					  s.add_development_dependency 'plist', '~>3.1'
 | 
				
			||||||
  s.add_development_dependency 'pry'
 | 
					  s.add_development_dependency 'pry'
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								grammars.yml
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								grammars.yml
									
									
									
									
									
								
							@@ -1,4 +1,3 @@
 | 
				
			|||||||
---
 | 
					 | 
				
			||||||
https://bitbucket.org/Clams/sublimesystemverilog/get/default.tar.gz:
 | 
					https://bitbucket.org/Clams/sublimesystemverilog/get/default.tar.gz:
 | 
				
			||||||
- source.systemverilog
 | 
					- source.systemverilog
 | 
				
			||||||
- source.ucfconstraints
 | 
					- source.ucfconstraints
 | 
				
			||||||
@@ -45,8 +44,6 @@ vendor/grammars/Isabelle.tmbundle:
 | 
				
			|||||||
- source.isabelle.theory
 | 
					- source.isabelle.theory
 | 
				
			||||||
vendor/grammars/JSyntax:
 | 
					vendor/grammars/JSyntax:
 | 
				
			||||||
- source.j
 | 
					- source.j
 | 
				
			||||||
vendor/grammars/Julia.tmbundle:
 | 
					 | 
				
			||||||
- source.julia
 | 
					 | 
				
			||||||
vendor/grammars/Lean.tmbundle:
 | 
					vendor/grammars/Lean.tmbundle:
 | 
				
			||||||
- source.lean
 | 
					- source.lean
 | 
				
			||||||
vendor/grammars/LiveScript.tmbundle:
 | 
					vendor/grammars/LiveScript.tmbundle:
 | 
				
			||||||
@@ -130,6 +127,9 @@ vendor/grammars/SublimePuppet:
 | 
				
			|||||||
- source.puppet
 | 
					- source.puppet
 | 
				
			||||||
vendor/grammars/SublimeXtend:
 | 
					vendor/grammars/SublimeXtend:
 | 
				
			||||||
- source.xtend
 | 
					- source.xtend
 | 
				
			||||||
 | 
					vendor/grammars/Syntax-highlighting-for-PostCSS:
 | 
				
			||||||
 | 
					- source.css.postcss.sugarss
 | 
				
			||||||
 | 
					- source.postcss
 | 
				
			||||||
vendor/grammars/TLA:
 | 
					vendor/grammars/TLA:
 | 
				
			||||||
- source.tla
 | 
					- source.tla
 | 
				
			||||||
vendor/grammars/TXL:
 | 
					vendor/grammars/TXL:
 | 
				
			||||||
@@ -192,6 +192,9 @@ vendor/grammars/atom-language-1c-bsl:
 | 
				
			|||||||
vendor/grammars/atom-language-clean:
 | 
					vendor/grammars/atom-language-clean:
 | 
				
			||||||
- source.clean
 | 
					- source.clean
 | 
				
			||||||
- text.restructuredtext.clean
 | 
					- text.restructuredtext.clean
 | 
				
			||||||
 | 
					vendor/grammars/atom-language-julia:
 | 
				
			||||||
 | 
					- source.julia
 | 
				
			||||||
 | 
					- source.julia.console
 | 
				
			||||||
vendor/grammars/atom-language-p4:
 | 
					vendor/grammars/atom-language-p4:
 | 
				
			||||||
- source.p4
 | 
					- source.p4
 | 
				
			||||||
vendor/grammars/atom-language-perl6:
 | 
					vendor/grammars/atom-language-perl6:
 | 
				
			||||||
@@ -340,6 +343,8 @@ vendor/grammars/java.tmbundle:
 | 
				
			|||||||
- source.java-properties
 | 
					- source.java-properties
 | 
				
			||||||
- text.html.jsp
 | 
					- text.html.jsp
 | 
				
			||||||
- text.junit-test-report
 | 
					- text.junit-test-report
 | 
				
			||||||
 | 
					vendor/grammars/javadoc.tmbundle:
 | 
				
			||||||
 | 
					- text.html.javadoc
 | 
				
			||||||
vendor/grammars/javascript-objective-j.tmbundle:
 | 
					vendor/grammars/javascript-objective-j.tmbundle:
 | 
				
			||||||
- source.js.objj
 | 
					- source.js.objj
 | 
				
			||||||
vendor/grammars/jflex.tmbundle:
 | 
					vendor/grammars/jflex.tmbundle:
 | 
				
			||||||
@@ -386,6 +391,8 @@ vendor/grammars/language-csound:
 | 
				
			|||||||
- source.csound-score
 | 
					- source.csound-score
 | 
				
			||||||
vendor/grammars/language-css:
 | 
					vendor/grammars/language-css:
 | 
				
			||||||
- source.css
 | 
					- source.css
 | 
				
			||||||
 | 
					vendor/grammars/language-cwl:
 | 
				
			||||||
 | 
					- source.cwl
 | 
				
			||||||
vendor/grammars/language-emacs-lisp:
 | 
					vendor/grammars/language-emacs-lisp:
 | 
				
			||||||
- source.emacs.lisp
 | 
					- source.emacs.lisp
 | 
				
			||||||
vendor/grammars/language-fontforge:
 | 
					vendor/grammars/language-fontforge:
 | 
				
			||||||
@@ -500,6 +507,8 @@ vendor/grammars/language-yaml:
 | 
				
			|||||||
- source.yaml
 | 
					- source.yaml
 | 
				
			||||||
vendor/grammars/language-yang:
 | 
					vendor/grammars/language-yang:
 | 
				
			||||||
- source.yang
 | 
					- source.yang
 | 
				
			||||||
 | 
					vendor/grammars/language-yara:
 | 
				
			||||||
 | 
					- source.yara
 | 
				
			||||||
vendor/grammars/latex.tmbundle:
 | 
					vendor/grammars/latex.tmbundle:
 | 
				
			||||||
- text.bibtex
 | 
					- text.bibtex
 | 
				
			||||||
- text.log.latex
 | 
					- text.log.latex
 | 
				
			||||||
@@ -566,7 +575,7 @@ vendor/grammars/opa.tmbundle:
 | 
				
			|||||||
- source.opa
 | 
					- source.opa
 | 
				
			||||||
vendor/grammars/openscad.tmbundle:
 | 
					vendor/grammars/openscad.tmbundle:
 | 
				
			||||||
- source.scad
 | 
					- source.scad
 | 
				
			||||||
vendor/grammars/oz-tmbundle/Syntaxes/Oz.tmLanguage:
 | 
					vendor/grammars/oz-tmbundle:
 | 
				
			||||||
- source.oz
 | 
					- source.oz
 | 
				
			||||||
vendor/grammars/parrot:
 | 
					vendor/grammars/parrot:
 | 
				
			||||||
- source.parrot.pir
 | 
					- source.parrot.pir
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -275,10 +275,8 @@ module Linguist
 | 
				
			|||||||
          # also--importantly--without having to duplicate many (potentially
 | 
					          # also--importantly--without having to duplicate many (potentially
 | 
				
			||||||
          # large) strings.
 | 
					          # large) strings.
 | 
				
			||||||
          begin
 | 
					          begin
 | 
				
			||||||
            encoded_newlines = ["\r\n", "\r", "\n"].
 | 
					            
 | 
				
			||||||
              map { |nl| nl.encode(ruby_encoding, "ASCII-8BIT").force_encoding(data.encoding) }
 | 
					            data.split(encoded_newlines_re, -1)
 | 
				
			||||||
 | 
					 | 
				
			||||||
            data.split(Regexp.union(encoded_newlines), -1)
 | 
					 | 
				
			||||||
          rescue Encoding::ConverterNotFoundError
 | 
					          rescue Encoding::ConverterNotFoundError
 | 
				
			||||||
            # The data is not splittable in the detected encoding.  Assume it's
 | 
					            # The data is not splittable in the detected encoding.  Assume it's
 | 
				
			||||||
            # one big line.
 | 
					            # one big line.
 | 
				
			||||||
@@ -289,6 +287,51 @@ module Linguist
 | 
				
			|||||||
        end
 | 
					        end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def encoded_newlines_re
 | 
				
			||||||
 | 
					      @encoded_newlines_re ||= Regexp.union(["\r\n", "\r", "\n"].
 | 
				
			||||||
 | 
					                                              map { |nl| nl.encode(ruby_encoding, "ASCII-8BIT").force_encoding(data.encoding) })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def first_lines(n)
 | 
				
			||||||
 | 
					      return lines[0...n] if defined? @lines
 | 
				
			||||||
 | 
					      return [] unless viewable? && data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      i, c = 0, 0
 | 
				
			||||||
 | 
					      while c < n && j = data.index(encoded_newlines_re, i)
 | 
				
			||||||
 | 
					        i = j + $&.length
 | 
				
			||||||
 | 
					        c += 1
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      data[0...i].split(encoded_newlines_re, -1)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def last_lines(n)
 | 
				
			||||||
 | 
					      if defined? @lines
 | 
				
			||||||
 | 
					        if n >= @lines.length
 | 
				
			||||||
 | 
					          @lines
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          lines[-n..-1]
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      return [] unless viewable? && data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      no_eol = true
 | 
				
			||||||
 | 
					      i, c = data.length, 0
 | 
				
			||||||
 | 
					      k = i
 | 
				
			||||||
 | 
					      while c < n && j = data.rindex(encoded_newlines_re, i - 1)
 | 
				
			||||||
 | 
					        if c == 0 && j + $&.length == i
 | 
				
			||||||
 | 
					          no_eol = false
 | 
				
			||||||
 | 
					          n += 1
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					        i = j
 | 
				
			||||||
 | 
					        k = j + $&.length
 | 
				
			||||||
 | 
					        c += 1
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      r = data[k..-1].split(encoded_newlines_re, -1)
 | 
				
			||||||
 | 
					      r.pop if !no_eol
 | 
				
			||||||
 | 
					      r
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Public: Get number of lines of code
 | 
					    # Public: Get number of lines of code
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # Requires Blob#data
 | 
					    # Requires Blob#data
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,8 @@ require 'linguist/tokenizer'
 | 
				
			|||||||
module Linguist
 | 
					module Linguist
 | 
				
			||||||
  # Language bayesian classifier.
 | 
					  # Language bayesian classifier.
 | 
				
			||||||
  class Classifier
 | 
					  class Classifier
 | 
				
			||||||
 | 
					    CLASSIFIER_CONSIDER_BYTES = 50 * 1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Public: Use the classifier to detect language of the blob.
 | 
					    # Public: Use the classifier to detect language of the blob.
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # blob               - An object that quacks like a blob.
 | 
					    # blob               - An object that quacks like a blob.
 | 
				
			||||||
@@ -17,7 +19,7 @@ module Linguist
 | 
				
			|||||||
    # Returns an Array of Language objects, most probable first.
 | 
					    # Returns an Array of Language objects, most probable first.
 | 
				
			||||||
    def self.call(blob, possible_languages)
 | 
					    def self.call(blob, possible_languages)
 | 
				
			||||||
      language_names = possible_languages.map(&:name)
 | 
					      language_names = possible_languages.map(&:name)
 | 
				
			||||||
      classify(Samples.cache, blob.data, language_names).map do |name, _|
 | 
					      classify(Samples.cache, blob.data[0...CLASSIFIER_CONSIDER_BYTES], language_names).map do |name, _|
 | 
				
			||||||
        Language[name] # Return the actual Language objects
 | 
					        Language[name] # Return the actual Language objects
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,21 +23,21 @@ module Linguist
 | 
				
			|||||||
    #
 | 
					    #
 | 
				
			||||||
    # Returns a String like '100644'
 | 
					    # Returns a String like '100644'
 | 
				
			||||||
    def mode
 | 
					    def mode
 | 
				
			||||||
      File.stat(@fullpath).mode.to_s(8)
 | 
					      @mode ||= File.stat(@fullpath).mode.to_s(8)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Public: Read file contents.
 | 
					    # Public: Read file contents.
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # Returns a String.
 | 
					    # Returns a String.
 | 
				
			||||||
    def data
 | 
					    def data
 | 
				
			||||||
      File.read(@fullpath)
 | 
					      @data ||= File.read(@fullpath)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Public: Get byte size
 | 
					    # Public: Get byte size
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # Returns an Integer.
 | 
					    # Returns an Integer.
 | 
				
			||||||
    def size
 | 
					    def size
 | 
				
			||||||
      File.size(@fullpath)
 | 
					      @size ||= File.size(@fullpath)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,6 +52,8 @@ module Linguist
 | 
				
			|||||||
    # Return true or false
 | 
					    # Return true or false
 | 
				
			||||||
    def generated?
 | 
					    def generated?
 | 
				
			||||||
      xcode_file? ||
 | 
					      xcode_file? ||
 | 
				
			||||||
 | 
					      cocoapods? ||
 | 
				
			||||||
 | 
					      carthage_build? ||
 | 
				
			||||||
      generated_net_designer_file? ||
 | 
					      generated_net_designer_file? ||
 | 
				
			||||||
      generated_net_specflow_feature_file? ||
 | 
					      generated_net_specflow_feature_file? ||
 | 
				
			||||||
      composer_lock? ||
 | 
					      composer_lock? ||
 | 
				
			||||||
@@ -95,6 +97,20 @@ module Linguist
 | 
				
			|||||||
      ['.nib', '.xcworkspacedata', '.xcuserstate'].include?(extname)
 | 
					      ['.nib', '.xcworkspacedata', '.xcuserstate'].include?(extname)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Internal: Is the blob part of Pods/, which contains dependencies not meant for humans in pull requests.
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # Returns true or false.
 | 
				
			||||||
 | 
					    def cocoapods?
 | 
				
			||||||
 | 
					      !!name.match(/(^Pods|\/Pods)\//)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Internal: Is the blob part of Carthage/Build/, which contains dependencies not meant for humans in pull requests.
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # Returns true or false.
 | 
				
			||||||
 | 
					    def carthage_build?
 | 
				
			||||||
 | 
					      !!name.match(/(^|\/)Carthage\/Build\//)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Internal: Is the blob minified files?
 | 
					    # Internal: Is the blob minified files?
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # Consider a file minified if the average line length is
 | 
					    # Consider a file minified if the average line length is
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
module Linguist
 | 
					module Linguist
 | 
				
			||||||
  # A collection of simple heuristics that can be used to better analyze languages.
 | 
					  # A collection of simple heuristics that can be used to better analyze languages.
 | 
				
			||||||
  class Heuristics
 | 
					  class Heuristics
 | 
				
			||||||
 | 
					    HEURISTICS_CONSIDER_BYTES = 50 * 1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Public: Use heuristics to detect language of the blob.
 | 
					    # Public: Use heuristics to detect language of the blob.
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # blob               - An object that quacks like a blob.
 | 
					    # blob               - An object that quacks like a blob.
 | 
				
			||||||
@@ -14,7 +16,7 @@ module Linguist
 | 
				
			|||||||
    #
 | 
					    #
 | 
				
			||||||
    # Returns an Array of languages, or empty if none matched or were inconclusive.
 | 
					    # Returns an Array of languages, or empty if none matched or were inconclusive.
 | 
				
			||||||
    def self.call(blob, candidates)
 | 
					    def self.call(blob, candidates)
 | 
				
			||||||
      data = blob.data
 | 
					      data = blob.data[0...HEURISTICS_CONSIDER_BYTES]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      @heuristics.each do |heuristic|
 | 
					      @heuristics.each do |heuristic|
 | 
				
			||||||
        if heuristic.matches?(blob.name, candidates)
 | 
					        if heuristic.matches?(blob.name, candidates)
 | 
				
			||||||
@@ -71,7 +73,17 @@ module Linguist
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Common heuristics
 | 
					    # Common heuristics
 | 
				
			||||||
 | 
					    CPlusPlusRegex = Regexp.union(
 | 
				
			||||||
 | 
					        /^\s*#\s*include <(cstdint|string|vector|map|list|array|bitset|queue|stack|forward_list|unordered_map|unordered_set|(i|o|io)stream)>/,
 | 
				
			||||||
 | 
					        /^\s*template\s*</,
 | 
				
			||||||
 | 
					        /^[ \t]*try/,
 | 
				
			||||||
 | 
					        /^[ \t]*catch\s*\(/,
 | 
				
			||||||
 | 
					        /^[ \t]*(class|(using[ \t]+)?namespace)\s+\w+/,
 | 
				
			||||||
 | 
					        /^[ \t]*(private|public|protected):$/,
 | 
				
			||||||
 | 
					        /std::\w+/)
 | 
				
			||||||
    ObjectiveCRegex = /^\s*(@(interface|class|protocol|property|end|synchronised|selector|implementation)\b|#import\s+.+\.h[">])/
 | 
					    ObjectiveCRegex = /^\s*(@(interface|class|protocol|property|end|synchronised|selector|implementation)\b|#import\s+.+\.h[">])/
 | 
				
			||||||
 | 
					    Perl5Regex = /\buse\s+(?:strict\b|v?5\.)/
 | 
				
			||||||
 | 
					    Perl6Regex = /^\s*(?:use\s+v6\b|\bmodule\b|\b(?:my\s+)?class\b)/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    disambiguate ".as" do |data|
 | 
					    disambiguate ".as" do |data|
 | 
				
			||||||
      if /^\s*(package\s+[a-z0-9_\.]+|import\s+[a-zA-Z0-9_\.]+;|class\s+[A-Za-z0-9_]+\s+extends\s+[A-Za-z0-9_]+)/.match(data)
 | 
					      if /^\s*(package\s+[a-z0-9_\.]+|import\s+[a-zA-Z0-9_\.]+;|class\s+[A-Za-z0-9_]+\s+extends\s+[A-Za-z0-9_]+)/.match(data)
 | 
				
			||||||
@@ -219,8 +231,7 @@ module Linguist
 | 
				
			|||||||
    disambiguate ".h" do |data|
 | 
					    disambiguate ".h" do |data|
 | 
				
			||||||
      if ObjectiveCRegex.match(data)
 | 
					      if ObjectiveCRegex.match(data)
 | 
				
			||||||
        Language["Objective-C"]
 | 
					        Language["Objective-C"]
 | 
				
			||||||
      elsif (/^\s*#\s*include <(cstdint|string|vector|map|list|array|bitset|queue|stack|forward_list|unordered_map|unordered_set|(i|o|io)stream)>/.match(data) ||
 | 
					      elsif CPlusPlusRegex.match(data)
 | 
				
			||||||
        /^\s*template\s*</.match(data) || /^[ \t]*try/.match(data) || /^[ \t]*catch\s*\(/.match(data) || /^[ \t]*(class|(using[ \t]+)?namespace)\s+\w+/.match(data) || /^[ \t]*(private|public|protected):$/.match(data) || /std::\w+/.match(data))
 | 
					 | 
				
			||||||
        Language["C++"]
 | 
					        Language["C++"]
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
@@ -350,33 +361,25 @@ module Linguist
 | 
				
			|||||||
    disambiguate ".pl" do |data|
 | 
					    disambiguate ".pl" do |data|
 | 
				
			||||||
      if /^[^#]*:-/.match(data)
 | 
					      if /^[^#]*:-/.match(data)
 | 
				
			||||||
        Language["Prolog"]
 | 
					        Language["Prolog"]
 | 
				
			||||||
      elsif /use strict|use\s+v?5\./.match(data)
 | 
					      elsif Perl5Regex.match(data)
 | 
				
			||||||
        Language["Perl"]
 | 
					        Language["Perl"]
 | 
				
			||||||
      elsif /^(use v6|(my )?class|module)/.match(data)
 | 
					      elsif Perl6Regex.match(data)
 | 
				
			||||||
        Language["Perl 6"]
 | 
					        Language["Perl 6"]
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    disambiguate ".pm" do |data|
 | 
					    disambiguate ".pm" do |data|
 | 
				
			||||||
      if /^\s*(?:use\s+v6\s*;|(?:\bmy\s+)?class|module)\b/.match(data)
 | 
					      if Perl5Regex.match(data)
 | 
				
			||||||
        Language["Perl 6"]
 | 
					 | 
				
			||||||
      elsif /\buse\s+(?:strict\b|v?5\.)/.match(data)
 | 
					 | 
				
			||||||
        Language["Perl"]
 | 
					        Language["Perl"]
 | 
				
			||||||
 | 
					      elsif Perl6Regex.match(data)
 | 
				
			||||||
 | 
					        Language["Perl 6"]
 | 
				
			||||||
      elsif /^\s*\/\* XPM \*\//.match(data)
 | 
					      elsif /^\s*\/\* XPM \*\//.match(data)
 | 
				
			||||||
        Language["XPM"]
 | 
					        Language["XPM"]
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    disambiguate ".pod", "Pod", "Perl" do |data|
 | 
					 | 
				
			||||||
      if /^=\w+\b/.match(data)
 | 
					 | 
				
			||||||
        Language["Pod"]
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        Language["Perl"]
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    disambiguate ".pro" do |data|
 | 
					    disambiguate ".pro" do |data|
 | 
				
			||||||
      if /^[^#]+:-/.match(data)
 | 
					      if /^[^\[#]+:-/.match(data)
 | 
				
			||||||
        Language["Prolog"]
 | 
					        Language["Prolog"]
 | 
				
			||||||
      elsif data.include?("last_client=")
 | 
					      elsif data.include?("last_client=")
 | 
				
			||||||
        Language["INI"]
 | 
					        Language["INI"]
 | 
				
			||||||
@@ -458,12 +461,12 @@ module Linguist
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    disambiguate ".t" do |data|
 | 
					    disambiguate ".t" do |data|
 | 
				
			||||||
      if /^\s*%[ \t]+|^\s*var\s+\w+\s*:=\s*\w+/.match(data)
 | 
					      if Perl5Regex.match(data)
 | 
				
			||||||
        Language["Turing"]
 | 
					 | 
				
			||||||
      elsif /^\s*(?:use\s+v6\s*;|\bmodule\b|\b(?:my\s+)?class\b)/.match(data)
 | 
					 | 
				
			||||||
        Language["Perl 6"]
 | 
					 | 
				
			||||||
      elsif /\buse\s+(?:strict\b|v?5\.)/.match(data)
 | 
					 | 
				
			||||||
        Language["Perl"]
 | 
					        Language["Perl"]
 | 
				
			||||||
 | 
					      elsif Perl6Regex.match(data)
 | 
				
			||||||
 | 
					        Language["Perl 6"]
 | 
				
			||||||
 | 
					      elsif /^\s*%[ \t]+|^\s*var\s+\w+\s*:=\s*\w+/.match(data)
 | 
				
			||||||
 | 
					        Language["Turing"]
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@@ -476,7 +479,7 @@ module Linguist
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    disambiguate ".ts" do |data|
 | 
					    disambiguate ".ts" do |data|
 | 
				
			||||||
      if data.include?("<TS")
 | 
					      if /<TS\b/.match(data)
 | 
				
			||||||
        Language["XML"]
 | 
					        Language["XML"]
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        Language["TypeScript"]
 | 
					        Language["TypeScript"]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -110,7 +110,7 @@ module Linguist
 | 
				
			|||||||
    # Returns the Language or nil if none was found.
 | 
					    # Returns the Language or nil if none was found.
 | 
				
			||||||
    def self.find_by_name(name)
 | 
					    def self.find_by_name(name)
 | 
				
			||||||
      return nil if !name.is_a?(String) || name.to_s.empty?
 | 
					      return nil if !name.is_a?(String) || name.to_s.empty?
 | 
				
			||||||
      name && (@name_index[name.downcase] || @name_index[name.split(',').first.downcase])
 | 
					      name && (@name_index[name.downcase] || @name_index[name.split(',', 2).first.downcase])
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Public: Look up Language by one of its aliases.
 | 
					    # Public: Look up Language by one of its aliases.
 | 
				
			||||||
@@ -125,7 +125,7 @@ module Linguist
 | 
				
			|||||||
    # Returns the Language or nil if none was found.
 | 
					    # Returns the Language or nil if none was found.
 | 
				
			||||||
    def self.find_by_alias(name)
 | 
					    def self.find_by_alias(name)
 | 
				
			||||||
      return nil if !name.is_a?(String) || name.to_s.empty?
 | 
					      return nil if !name.is_a?(String) || name.to_s.empty?
 | 
				
			||||||
      name && (@alias_index[name.downcase] || @alias_index[name.split(',').first.downcase])
 | 
					      name && (@alias_index[name.downcase] || @alias_index[name.split(',', 2).first.downcase])
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Public: Look up Languages by filename.
 | 
					    # Public: Look up Languages by filename.
 | 
				
			||||||
@@ -219,10 +219,7 @@ module Linguist
 | 
				
			|||||||
      lang = @index[name.downcase]
 | 
					      lang = @index[name.downcase]
 | 
				
			||||||
      return lang if lang
 | 
					      return lang if lang
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      name = name.split(',').first
 | 
					      @index[name.split(',', 2).first.downcase]
 | 
				
			||||||
      return nil if name.to_s.empty?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      @index[name.downcase]
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Public: A List of popular languages
 | 
					    # Public: A List of popular languages
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -807,6 +807,19 @@ Common Lisp:
 | 
				
			|||||||
  codemirror_mode: commonlisp
 | 
					  codemirror_mode: commonlisp
 | 
				
			||||||
  codemirror_mime_type: text/x-common-lisp
 | 
					  codemirror_mime_type: text/x-common-lisp
 | 
				
			||||||
  language_id: 66
 | 
					  language_id: 66
 | 
				
			||||||
 | 
					Common Workflow Language:
 | 
				
			||||||
 | 
					  alias: cwl
 | 
				
			||||||
 | 
					  type: programming
 | 
				
			||||||
 | 
					  ace_mode: yaml
 | 
				
			||||||
 | 
					  codemirror_mode: yaml
 | 
				
			||||||
 | 
					  codemirror_mime_type: text/x-yaml
 | 
				
			||||||
 | 
					  extensions:
 | 
				
			||||||
 | 
					  - ".cwl"
 | 
				
			||||||
 | 
					  interpreters:
 | 
				
			||||||
 | 
					  - cwl-runner
 | 
				
			||||||
 | 
					  color: "#B5314C"
 | 
				
			||||||
 | 
					  tm_scope: source.cwl
 | 
				
			||||||
 | 
					  language_id: 988547172
 | 
				
			||||||
Component Pascal:
 | 
					Component Pascal:
 | 
				
			||||||
  type: programming
 | 
					  type: programming
 | 
				
			||||||
  color: "#B0CE4E"
 | 
					  color: "#B0CE4E"
 | 
				
			||||||
@@ -1144,6 +1157,15 @@ Ecere Projects:
 | 
				
			|||||||
  codemirror_mode: javascript
 | 
					  codemirror_mode: javascript
 | 
				
			||||||
  codemirror_mime_type: application/json
 | 
					  codemirror_mime_type: application/json
 | 
				
			||||||
  language_id: 98
 | 
					  language_id: 98
 | 
				
			||||||
 | 
					Edje Data Collection:
 | 
				
			||||||
 | 
					  type: data
 | 
				
			||||||
 | 
					  extensions:
 | 
				
			||||||
 | 
					  - ".edc"
 | 
				
			||||||
 | 
					  tm_scope: source.json
 | 
				
			||||||
 | 
					  ace_mode: json
 | 
				
			||||||
 | 
					  codemirror_mode: javascript
 | 
				
			||||||
 | 
					  codemirror_mime_type: application/json
 | 
				
			||||||
 | 
					  language_id: 342840478
 | 
				
			||||||
Eiffel:
 | 
					Eiffel:
 | 
				
			||||||
  type: programming
 | 
					  type: programming
 | 
				
			||||||
  color: "#946d57"
 | 
					  color: "#946d57"
 | 
				
			||||||
@@ -1921,6 +1943,7 @@ IRC log:
 | 
				
			|||||||
  language_id: 164
 | 
					  language_id: 164
 | 
				
			||||||
Idris:
 | 
					Idris:
 | 
				
			||||||
  type: programming
 | 
					  type: programming
 | 
				
			||||||
 | 
					  color: "#b30000"
 | 
				
			||||||
  extensions:
 | 
					  extensions:
 | 
				
			||||||
  - ".idr"
 | 
					  - ".idr"
 | 
				
			||||||
  - ".lidr"
 | 
					  - ".lidr"
 | 
				
			||||||
@@ -2235,9 +2258,9 @@ Kotlin:
 | 
				
			|||||||
  language_id: 189
 | 
					  language_id: 189
 | 
				
			||||||
LFE:
 | 
					LFE:
 | 
				
			||||||
  type: programming
 | 
					  type: programming
 | 
				
			||||||
 | 
					  color: "#4C3023"
 | 
				
			||||||
  extensions:
 | 
					  extensions:
 | 
				
			||||||
  - ".lfe"
 | 
					  - ".lfe"
 | 
				
			||||||
  group: Erlang
 | 
					 | 
				
			||||||
  tm_scope: source.lisp
 | 
					  tm_scope: source.lisp
 | 
				
			||||||
  ace_mode: lisp
 | 
					  ace_mode: lisp
 | 
				
			||||||
  codemirror_mode: commonlisp
 | 
					  codemirror_mode: commonlisp
 | 
				
			||||||
@@ -3313,7 +3336,6 @@ Perl:
 | 
				
			|||||||
  - ".ph"
 | 
					  - ".ph"
 | 
				
			||||||
  - ".plx"
 | 
					  - ".plx"
 | 
				
			||||||
  - ".pm"
 | 
					  - ".pm"
 | 
				
			||||||
  - ".pod"
 | 
					 | 
				
			||||||
  - ".psgi"
 | 
					  - ".psgi"
 | 
				
			||||||
  - ".t"
 | 
					  - ".t"
 | 
				
			||||||
  filenames:
 | 
					  filenames:
 | 
				
			||||||
@@ -3418,6 +3440,14 @@ Pony:
 | 
				
			|||||||
  tm_scope: source.pony
 | 
					  tm_scope: source.pony
 | 
				
			||||||
  ace_mode: text
 | 
					  ace_mode: text
 | 
				
			||||||
  language_id: 290
 | 
					  language_id: 290
 | 
				
			||||||
 | 
					PostCSS:
 | 
				
			||||||
 | 
					  type: markup
 | 
				
			||||||
 | 
					  tm_scope: source.postcss
 | 
				
			||||||
 | 
					  group: CSS
 | 
				
			||||||
 | 
					  extensions:
 | 
				
			||||||
 | 
					  - ".pcss"
 | 
				
			||||||
 | 
					  ace_mode: text
 | 
				
			||||||
 | 
					  language_id: 262764437
 | 
				
			||||||
PostScript:
 | 
					PostScript:
 | 
				
			||||||
  type: markup
 | 
					  type: markup
 | 
				
			||||||
  color: "#da291c"
 | 
					  color: "#da291c"
 | 
				
			||||||
@@ -3583,6 +3613,7 @@ Python:
 | 
				
			|||||||
  - ".gclient"
 | 
					  - ".gclient"
 | 
				
			||||||
  - BUCK
 | 
					  - BUCK
 | 
				
			||||||
  - BUILD
 | 
					  - BUILD
 | 
				
			||||||
 | 
					  - BUILD.bazel
 | 
				
			||||||
  - SConscript
 | 
					  - SConscript
 | 
				
			||||||
  - SConstruct
 | 
					  - SConstruct
 | 
				
			||||||
  - Snakefile
 | 
					  - Snakefile
 | 
				
			||||||
@@ -4404,6 +4435,14 @@ Sublime Text Config:
 | 
				
			|||||||
  - ".sublime_metrics"
 | 
					  - ".sublime_metrics"
 | 
				
			||||||
  - ".sublime_session"
 | 
					  - ".sublime_session"
 | 
				
			||||||
  language_id: 423
 | 
					  language_id: 423
 | 
				
			||||||
 | 
					SugarSS:
 | 
				
			||||||
 | 
					  type: markup
 | 
				
			||||||
 | 
					  tm_scope: source.css.postcss.sugarss
 | 
				
			||||||
 | 
					  group: CSS
 | 
				
			||||||
 | 
					  extensions:
 | 
				
			||||||
 | 
					  - ".sss"
 | 
				
			||||||
 | 
					  ace_mode: text
 | 
				
			||||||
 | 
					  language_id: 826404698
 | 
				
			||||||
SuperCollider:
 | 
					SuperCollider:
 | 
				
			||||||
  type: programming
 | 
					  type: programming
 | 
				
			||||||
  color: "#46390b"
 | 
					  color: "#46390b"
 | 
				
			||||||
@@ -5110,6 +5149,14 @@ YANG:
 | 
				
			|||||||
  tm_scope: source.yang
 | 
					  tm_scope: source.yang
 | 
				
			||||||
  ace_mode: text
 | 
					  ace_mode: text
 | 
				
			||||||
  language_id: 408
 | 
					  language_id: 408
 | 
				
			||||||
 | 
					YARA:
 | 
				
			||||||
 | 
					  type: data
 | 
				
			||||||
 | 
					  ace_mode: text
 | 
				
			||||||
 | 
					  extensions:
 | 
				
			||||||
 | 
					  - ".yar"
 | 
				
			||||||
 | 
					  - ".yara"
 | 
				
			||||||
 | 
					  tm_scope: source.yara
 | 
				
			||||||
 | 
					  language_id: 805122868
 | 
				
			||||||
Yacc:
 | 
					Yacc:
 | 
				
			||||||
  type: programming
 | 
					  type: programming
 | 
				
			||||||
  extensions:
 | 
					  extensions:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,8 +109,8 @@ module Linguist
 | 
				
			|||||||
      # Returns an Array with one Language if the blob has a Vim or Emacs modeline
 | 
					      # Returns an Array with one Language if the blob has a Vim or Emacs modeline
 | 
				
			||||||
      # that matches a Language name or alias. Returns an empty array if no match.
 | 
					      # that matches a Language name or alias. Returns an empty array if no match.
 | 
				
			||||||
      def self.call(blob, _ = nil)
 | 
					      def self.call(blob, _ = nil)
 | 
				
			||||||
        header = blob.lines.first(SEARCH_SCOPE).join("\n")
 | 
					        header = blob.first_lines(SEARCH_SCOPE).join("\n")
 | 
				
			||||||
        footer = blob.lines.last(SEARCH_SCOPE).join("\n")
 | 
					        footer = blob.last_lines(SEARCH_SCOPE).join("\n")
 | 
				
			||||||
        Array(Language.find_by_alias(modeline(header + footer)))
 | 
					        Array(Language.find_by_alias(modeline(header + footer)))
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
require 'strscan'
 | 
					require 'strscan'
 | 
				
			||||||
 | 
					require 'linguist/linguist'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module Linguist
 | 
					module Linguist
 | 
				
			||||||
  # Generic programming language tokenizer.
 | 
					  # Generic programming language tokenizer.
 | 
				
			||||||
@@ -15,191 +16,5 @@ module Linguist
 | 
				
			|||||||
    def self.tokenize(data)
 | 
					    def self.tokenize(data)
 | 
				
			||||||
      new.extract_tokens(data)
 | 
					      new.extract_tokens(data)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Read up to 100KB
 | 
					 | 
				
			||||||
    BYTE_LIMIT = 100_000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Start state on token, ignore anything till the next newline
 | 
					 | 
				
			||||||
    SINGLE_LINE_COMMENTS = [
 | 
					 | 
				
			||||||
      '//', # C
 | 
					 | 
				
			||||||
      '--', # Ada, Haskell, AppleScript
 | 
					 | 
				
			||||||
      '#',  # Ruby
 | 
					 | 
				
			||||||
      '%',  # Tex
 | 
					 | 
				
			||||||
      '"',  # Vim
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Start state on opening token, ignore anything until the closing
 | 
					 | 
				
			||||||
    # token is reached.
 | 
					 | 
				
			||||||
    MULTI_LINE_COMMENTS = [
 | 
					 | 
				
			||||||
      ['/*', '*/'],    # C
 | 
					 | 
				
			||||||
      ['<!--', '-->'], # XML
 | 
					 | 
				
			||||||
      ['{-', '-}'],    # Haskell
 | 
					 | 
				
			||||||
      ['(*', '*)'],    # Coq
 | 
					 | 
				
			||||||
      ['"""', '"""'],  # Python
 | 
					 | 
				
			||||||
      ["'''", "'''"]   # Python
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    START_SINGLE_LINE_COMMENT =  Regexp.compile(SINGLE_LINE_COMMENTS.map { |c|
 | 
					 | 
				
			||||||
      "\s*#{Regexp.escape(c)} "
 | 
					 | 
				
			||||||
    }.join("|"))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    START_MULTI_LINE_COMMENT =  Regexp.compile(MULTI_LINE_COMMENTS.map { |c|
 | 
					 | 
				
			||||||
      Regexp.escape(c[0])
 | 
					 | 
				
			||||||
    }.join("|"))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Internal: Extract generic tokens from data.
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # data - String to scan.
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # Examples
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    #   extract_tokens("printf('Hello')")
 | 
					 | 
				
			||||||
    #   # => ['printf', '(', ')']
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # Returns Array of token Strings.
 | 
					 | 
				
			||||||
    def extract_tokens(data)
 | 
					 | 
				
			||||||
      s = StringScanner.new(data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      tokens = []
 | 
					 | 
				
			||||||
      until s.eos?
 | 
					 | 
				
			||||||
        break if s.pos >= BYTE_LIMIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if token = s.scan(/^#!.+$/)
 | 
					 | 
				
			||||||
          if name = extract_shebang(token)
 | 
					 | 
				
			||||||
            tokens << "SHEBANG#!#{name}"
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Single line comment
 | 
					 | 
				
			||||||
        elsif s.beginning_of_line? && token = s.scan(START_SINGLE_LINE_COMMENT)
 | 
					 | 
				
			||||||
          # tokens << token.strip
 | 
					 | 
				
			||||||
          s.skip_until(/\n|\Z/)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Multiline comments
 | 
					 | 
				
			||||||
        elsif token = s.scan(START_MULTI_LINE_COMMENT)
 | 
					 | 
				
			||||||
          # tokens << token
 | 
					 | 
				
			||||||
          close_token = MULTI_LINE_COMMENTS.assoc(token)[1]
 | 
					 | 
				
			||||||
          s.skip_until(Regexp.compile(Regexp.escape(close_token)))
 | 
					 | 
				
			||||||
          # tokens << close_token
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Skip single or double quoted strings
 | 
					 | 
				
			||||||
        elsif s.scan(/"/)
 | 
					 | 
				
			||||||
          if s.peek(1) == "\""
 | 
					 | 
				
			||||||
            s.getch
 | 
					 | 
				
			||||||
          else
 | 
					 | 
				
			||||||
            s.skip_until(/(?<!\\)"/)
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
        elsif s.scan(/'/)
 | 
					 | 
				
			||||||
          if s.peek(1) == "'"
 | 
					 | 
				
			||||||
            s.getch
 | 
					 | 
				
			||||||
          else
 | 
					 | 
				
			||||||
            s.skip_until(/(?<!\\)'/)
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Skip number literals
 | 
					 | 
				
			||||||
        elsif s.scan(/(0x\h(\h|\.)*|\d(\d|\.)*)([uU][lL]{0,2}|([eE][-+]\d*)?[fFlL]*)/)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # SGML style brackets
 | 
					 | 
				
			||||||
        elsif token = s.scan(/<[^\s<>][^<>]*>/)
 | 
					 | 
				
			||||||
          extract_sgml_tokens(token).each { |t| tokens << t }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Common programming punctuation
 | 
					 | 
				
			||||||
        elsif token = s.scan(/;|\{|\}|\(|\)|\[|\]/)
 | 
					 | 
				
			||||||
          tokens << token
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Regular token
 | 
					 | 
				
			||||||
        elsif token = s.scan(/[\w\.@#\/\*]+/)
 | 
					 | 
				
			||||||
          tokens << token
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Common operators
 | 
					 | 
				
			||||||
        elsif token = s.scan(/<<?|\+|\-|\*|\/|%|&&?|\|\|?/)
 | 
					 | 
				
			||||||
          tokens << token
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          s.getch
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      tokens
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Internal: Extract normalized shebang command token.
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # Examples
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    #   extract_shebang("#!/usr/bin/ruby")
 | 
					 | 
				
			||||||
    #   # => "ruby"
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    #   extract_shebang("#!/usr/bin/env node")
 | 
					 | 
				
			||||||
    #   # => "node"
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    #   extract_shebang("#!/usr/bin/env A=B foo=bar awk -f")
 | 
					 | 
				
			||||||
    #   # => "awk"
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # Returns String token or nil it couldn't be parsed.
 | 
					 | 
				
			||||||
    def extract_shebang(data)
 | 
					 | 
				
			||||||
      s = StringScanner.new(data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if path = s.scan(/^#!\s*\S+/)
 | 
					 | 
				
			||||||
        script = path.split('/').last
 | 
					 | 
				
			||||||
        if script == 'env'
 | 
					 | 
				
			||||||
          s.scan(/\s+/)
 | 
					 | 
				
			||||||
          s.scan(/.*=[^\s]+\s+/)
 | 
					 | 
				
			||||||
          script = s.scan(/\S+/)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
        script = script[/[^\d]+/, 0] if script
 | 
					 | 
				
			||||||
        return script
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      nil
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Internal: Extract tokens from inside SGML tag.
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # data - SGML tag String.
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # Examples
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    #   extract_sgml_tokens("<a href='' class=foo>")
 | 
					 | 
				
			||||||
    #   # => ["<a>", "href="]
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # Returns Array of token Strings.
 | 
					 | 
				
			||||||
    def extract_sgml_tokens(data)
 | 
					 | 
				
			||||||
      s = StringScanner.new(data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      tokens = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      until s.eos?
 | 
					 | 
				
			||||||
        # Emit start token
 | 
					 | 
				
			||||||
        if token = s.scan(/<\/?[^\s>]+/)
 | 
					 | 
				
			||||||
          tokens << "#{token}>"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Emit attributes with trailing =
 | 
					 | 
				
			||||||
        elsif token = s.scan(/\w+=/)
 | 
					 | 
				
			||||||
          tokens << token
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          # Then skip over attribute value
 | 
					 | 
				
			||||||
          if s.scan(/"/)
 | 
					 | 
				
			||||||
            s.skip_until(/[^\\]"/)
 | 
					 | 
				
			||||||
          elsif s.scan(/'/)
 | 
					 | 
				
			||||||
            s.skip_until(/[^\\]'/)
 | 
					 | 
				
			||||||
          else
 | 
					 | 
				
			||||||
            s.skip_until(/\w+/)
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Emit lone attributes
 | 
					 | 
				
			||||||
        elsif token = s.scan(/\w+/)
 | 
					 | 
				
			||||||
          tokens << token
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Stop at the end of the tag
 | 
					 | 
				
			||||||
        elsif s.scan(/>/)
 | 
					 | 
				
			||||||
          s.terminate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          s.getch
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      tokens
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,9 +19,7 @@
 | 
				
			|||||||
- (^|/)dist/
 | 
					- (^|/)dist/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# C deps
 | 
					# C deps
 | 
				
			||||||
#  https://github.com/joyent/node
 | 
					 | 
				
			||||||
- ^deps/
 | 
					- ^deps/
 | 
				
			||||||
- ^tools/
 | 
					 | 
				
			||||||
- (^|/)configure$
 | 
					- (^|/)configure$
 | 
				
			||||||
- (^|/)config.guess$
 | 
					- (^|/)config.guess$
 | 
				
			||||||
- (^|/)config.sub$
 | 
					- (^|/)config.sub$
 | 
				
			||||||
@@ -65,6 +63,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Font Awesome
 | 
					# Font Awesome
 | 
				
			||||||
- (^|/)font-awesome\.(css|less|scss|styl)$
 | 
					- (^|/)font-awesome\.(css|less|scss|styl)$
 | 
				
			||||||
 | 
					- (^|/)font-awesome/.*\.(css|less|scss|styl)$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Foundation css
 | 
					# Foundation css
 | 
				
			||||||
- (^|/)foundation\.(css|less|scss|styl)$
 | 
					- (^|/)foundation\.(css|less|scss|styl)$
 | 
				
			||||||
@@ -81,6 +80,9 @@
 | 
				
			|||||||
# Animate.css
 | 
					# Animate.css
 | 
				
			||||||
- (^|/)animate\.(css|less|scss|styl)$
 | 
					- (^|/)animate\.(css|less|scss|styl)$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Select2
 | 
				
			||||||
 | 
					- (^|/)select2/.*\.(css|scss|js)$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Vendored dependencies
 | 
					# Vendored dependencies
 | 
				
			||||||
- third[-_]?party/
 | 
					- third[-_]?party/
 | 
				
			||||||
- 3rd[-_]?party/
 | 
					- 3rd[-_]?party/
 | 
				
			||||||
@@ -119,6 +121,15 @@
 | 
				
			|||||||
# jQuery File Upload
 | 
					# jQuery File Upload
 | 
				
			||||||
- (^|/)jquery\.fileupload(-\w+)?\.js$
 | 
					- (^|/)jquery\.fileupload(-\w+)?\.js$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# jQuery dataTables
 | 
				
			||||||
 | 
					- jquery.dataTables.js
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# bootboxjs
 | 
				
			||||||
 | 
					- bootbox.js
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# pdf-worker
 | 
				
			||||||
 | 
					- pdf.worker.js
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Slick
 | 
					# Slick
 | 
				
			||||||
- (^|/)slick\.\w+.js$
 | 
					- (^|/)slick\.\w+.js$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -230,10 +241,7 @@
 | 
				
			|||||||
- \.imageset/
 | 
					- \.imageset/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Carthage
 | 
					# Carthage
 | 
				
			||||||
- ^Carthage/
 | 
					- (^|/)Carthage/
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Cocoapods
 | 
					 | 
				
			||||||
- ^Pods/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Sparkle
 | 
					# Sparkle
 | 
				
			||||||
- (^|/)Sparkle/
 | 
					- (^|/)Sparkle/
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
module Linguist
 | 
					module Linguist
 | 
				
			||||||
  VERSION = "5.3.0"
 | 
					  VERSION = "5.3.3"
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "repository": "https://github.com/github/linguist",
 | 
					 | 
				
			||||||
  "dependencies": {
 | 
					 | 
				
			||||||
    "season": "~>5.4"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "license": "MIT"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										36
									
								
								samples/Common Workflow Language/trunk-peak-score.cwl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								samples/Common Workflow Language/trunk-peak-score.cwl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env cwl-runner
 | 
				
			||||||
 | 
					# Originally from
 | 
				
			||||||
 | 
					# https://github.com/Duke-GCB/GGR-cwl/blob/54e897263a702ff1074c8ac814b4bf7205d140dd/utils/trunk-peak-score.cwl
 | 
				
			||||||
 | 
					# Released under the MIT License:
 | 
				
			||||||
 | 
					# https://github.com/Duke-GCB/GGR-cwl/blob/54e897263a702ff1074c8ac814b4bf7205d140dd/LICENSE
 | 
				
			||||||
 | 
					# Converted to CWL v1.0 syntax using
 | 
				
			||||||
 | 
					# https://github.com/common-workflow-language/cwl-upgrader
 | 
				
			||||||
 | 
					# and polished by Michael R. Crusoe <mrc@commonwl.org>
 | 
				
			||||||
 | 
					# All modifications also released under the MIT License
 | 
				
			||||||
 | 
					cwlVersion: v1.0
 | 
				
			||||||
 | 
					class: CommandLineTool
 | 
				
			||||||
 | 
					doc: Trunk scores in ENCODE bed6+4 files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hints:
 | 
				
			||||||
 | 
					  DockerRequirement:
 | 
				
			||||||
 | 
					    dockerPull: dukegcb/workflow-utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inputs:
 | 
				
			||||||
 | 
					  peaks:
 | 
				
			||||||
 | 
					    type: File
 | 
				
			||||||
 | 
					  sep:
 | 
				
			||||||
 | 
					    type: string
 | 
				
			||||||
 | 
					    default: \t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					outputs:
 | 
				
			||||||
 | 
					  trunked_scores_peaks:
 | 
				
			||||||
 | 
					    type: stdout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					baseCommand: awk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					arguments:
 | 
				
			||||||
 | 
					- -F $(inputs.sep)
 | 
				
			||||||
 | 
					- BEGIN{OFS=FS}$5>1000{$5=1000}{print}
 | 
				
			||||||
 | 
					- $(inputs.peaks.path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					stdout: $(inputs.peaks.nameroot).trunked_scores$(inputs.peaks.nameext)
 | 
				
			||||||
							
								
								
									
										2061
									
								
								samples/Edje Data Collection/mild.edc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2061
									
								
								samples/Edje Data Collection/mild.edc
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										13
									
								
								samples/PostCSS/sample.pcss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								samples/PostCSS/sample.pcss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					@define-mixin size $size {
 | 
				
			||||||
 | 
					  width: $size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$big: 100px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Main block */
 | 
				
			||||||
 | 
					.block {
 | 
				
			||||||
 | 
					  &_logo {
 | 
				
			||||||
 | 
					    background: inline("./logo.png");
 | 
				
			||||||
 | 
					    @mixin size $big;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								samples/SugarSS/sample.sss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								samples/SugarSS/sample.sss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					@define-mixin size $size
 | 
				
			||||||
 | 
					  width: $size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$big: 100px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Main block
 | 
				
			||||||
 | 
					.block
 | 
				
			||||||
 | 
					  &_logo
 | 
				
			||||||
 | 
					    background: inline("./logo.png")
 | 
				
			||||||
 | 
					    @mixin size $big
 | 
				
			||||||
							
								
								
									
										102
									
								
								samples/TypeScript/cache.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								samples/TypeScript/cache.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
				
			|||||||
 | 
					import { DocumentNode } from 'graphql';
 | 
				
			||||||
 | 
					import { getFragmentQueryDocument } from 'apollo-utilities';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { DataProxy, Cache } from './types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Transaction<T> = (c: ApolloCache<T>) => void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export abstract class ApolloCache<TSerialized> implements DataProxy {
 | 
				
			||||||
 | 
					  // required to implement
 | 
				
			||||||
 | 
					  // core API
 | 
				
			||||||
 | 
					  public abstract read<T>(query: Cache.ReadOptions): T;
 | 
				
			||||||
 | 
					  public abstract write(write: Cache.WriteOptions): void;
 | 
				
			||||||
 | 
					  public abstract diff<T>(query: Cache.DiffOptions): Cache.DiffResult<T>;
 | 
				
			||||||
 | 
					  public abstract watch(watch: Cache.WatchOptions): () => void;
 | 
				
			||||||
 | 
					  public abstract evict(query: Cache.EvictOptions): Cache.EvictionResult;
 | 
				
			||||||
 | 
					  public abstract reset(): Promise<void>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // intializer / offline / ssr API
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Replaces existing state in the cache (if any) with the values expressed by
 | 
				
			||||||
 | 
					   * `serializedState`.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * Called when hydrating a cache (server side rendering, or offline storage),
 | 
				
			||||||
 | 
					   * and also (potentially) during hot reloads.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public abstract restore(
 | 
				
			||||||
 | 
					    serializedState: TSerialized,
 | 
				
			||||||
 | 
					  ): ApolloCache<TSerialized>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Exposes the cache's complete state, in a serializable format for later restoration.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public abstract extract(optimistic: boolean): TSerialized;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // optimistic API
 | 
				
			||||||
 | 
					  public abstract removeOptimistic(id: string): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // transactional API
 | 
				
			||||||
 | 
					  public abstract performTransaction(
 | 
				
			||||||
 | 
					    transaction: Transaction<TSerialized>,
 | 
				
			||||||
 | 
					  ): void;
 | 
				
			||||||
 | 
					  public abstract recordOptimisticTransaction(
 | 
				
			||||||
 | 
					    transaction: Transaction<TSerialized>,
 | 
				
			||||||
 | 
					    id: string,
 | 
				
			||||||
 | 
					  ): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // optional API
 | 
				
			||||||
 | 
					  public transformDocument(document: DocumentNode): DocumentNode {
 | 
				
			||||||
 | 
					    return document;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // experimental
 | 
				
			||||||
 | 
					  public transformForLink(document: DocumentNode): DocumentNode {
 | 
				
			||||||
 | 
					    return document;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // DataProxy API
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param options
 | 
				
			||||||
 | 
					   * @param optimistic
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public readQuery<QueryType>(
 | 
				
			||||||
 | 
					    options: DataProxy.Query,
 | 
				
			||||||
 | 
					    optimistic: boolean = false,
 | 
				
			||||||
 | 
					  ): QueryType {
 | 
				
			||||||
 | 
					    return this.read({
 | 
				
			||||||
 | 
					      query: options.query,
 | 
				
			||||||
 | 
					      variables: options.variables,
 | 
				
			||||||
 | 
					      optimistic,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public readFragment<FragmentType>(
 | 
				
			||||||
 | 
					    options: DataProxy.Fragment,
 | 
				
			||||||
 | 
					    optimistic: boolean = false,
 | 
				
			||||||
 | 
					  ): FragmentType | null {
 | 
				
			||||||
 | 
					    return this.read({
 | 
				
			||||||
 | 
					      query: getFragmentQueryDocument(options.fragment, options.fragmentName),
 | 
				
			||||||
 | 
					      variables: options.variables,
 | 
				
			||||||
 | 
					      rootId: options.id,
 | 
				
			||||||
 | 
					      optimistic,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public writeQuery(options: Cache.WriteQueryOptions): void {
 | 
				
			||||||
 | 
					    this.write({
 | 
				
			||||||
 | 
					      dataId: 'ROOT_QUERY',
 | 
				
			||||||
 | 
					      result: options.data,
 | 
				
			||||||
 | 
					      query: options.query,
 | 
				
			||||||
 | 
					      variables: options.variables,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public writeFragment(options: Cache.WriteFragmentOptions): void {
 | 
				
			||||||
 | 
					    this.write({
 | 
				
			||||||
 | 
					      dataId: options.id,
 | 
				
			||||||
 | 
					      result: options.data,
 | 
				
			||||||
 | 
					      variables: options.variables,
 | 
				
			||||||
 | 
					      query: getFragmentQueryDocument(options.fragment, options.fragmentName),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								samples/YARA/OfExample.yar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								samples/YARA/OfExample.yar
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					rule OfExample2
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    strings:
 | 
				
			||||||
 | 
					        $foo1 = "foo1"
 | 
				
			||||||
 | 
					        $foo2 = "foo2"
 | 
				
			||||||
 | 
					        $foo3 = "foo3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    condition:
 | 
				
			||||||
 | 
					        2 of ($foo*)  // equivalent to 2 of ($foo1,$foo2,$foo3)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rule OfExample3
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    strings:
 | 
				
			||||||
 | 
					        $foo1 = "foo1"
 | 
				
			||||||
 | 
					        $foo2 = "foo2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $bar1 = "bar1"
 | 
				
			||||||
 | 
					        $bar2 = "bar2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    condition:
 | 
				
			||||||
 | 
					        3 of ($foo*,$bar1,$bar2)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								samples/YARA/example.yara
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								samples/YARA/example.yara
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					rule silent_banker : banker
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    meta:
 | 
				
			||||||
 | 
					        description = "This is just an example"
 | 
				
			||||||
 | 
					        thread_level = 3
 | 
				
			||||||
 | 
					        in_the_wild = true
 | 
				
			||||||
 | 
					    strings:
 | 
				
			||||||
 | 
					        $a = {6A 40 68 00 30 00 00 6A 14 8D 91}
 | 
				
			||||||
 | 
					        $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}
 | 
				
			||||||
 | 
					        $c = "UVODFRYSIHLNWPEJXQZAKCBGMT"
 | 
				
			||||||
 | 
					    condition:
 | 
				
			||||||
 | 
					        $a or $b or $c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								samples/YARA/true.yar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								samples/YARA/true.yar
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					rule test { condition: true }
 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
#!/usr/bin/env ruby
 | 
					#!/usr/bin/env ruby
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require "optparse"
 | 
					require "optparse"
 | 
				
			||||||
 | 
					require "open3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ROOT = File.expand_path("../../", __FILE__)
 | 
					ROOT = File.expand_path("../../", __FILE__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,6 +43,17 @@ def log(msg)
 | 
				
			|||||||
  puts msg if $verbose
 | 
					  puts msg if $verbose
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def command(*args)
 | 
				
			||||||
 | 
					  log "$ #{args.join(' ')}"
 | 
				
			||||||
 | 
					  output, status = Open3.capture2e(*args)
 | 
				
			||||||
 | 
					  if !status.success?
 | 
				
			||||||
 | 
					    output.each_line do |line|
 | 
				
			||||||
 | 
					      log "  > #{line}"
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    warn "Command failed. Aborting."
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
usage = """Usage:
 | 
					usage = """Usage:
 | 
				
			||||||
  #{$0} [-v|--verbose] [--replace grammar] url
 | 
					  #{$0} [-v|--verbose] [--replace grammar] url
 | 
				
			||||||
@@ -51,12 +63,12 @@ Examples:
 | 
				
			|||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$replace = nil
 | 
					$replace = nil
 | 
				
			||||||
$verbose = false
 | 
					$verbose = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OptionParser.new do |opts|
 | 
					OptionParser.new do |opts|
 | 
				
			||||||
  opts.banner = usage
 | 
					  opts.banner = usage
 | 
				
			||||||
  opts.on("-v", "--verbose", "Print verbose feedback to STDOUT") do
 | 
					  opts.on("-q", "--quiet", "Do not print output unless there's a failure") do
 | 
				
			||||||
    $verbose = true
 | 
					    $verbose = false
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  opts.on("-rSUBMODULE", "--replace=SUBMODDULE", "Replace an existing grammar submodule.") do |name|
 | 
					  opts.on("-rSUBMODULE", "--replace=SUBMODDULE", "Replace an existing grammar submodule.") do |name|
 | 
				
			||||||
    $replace = name
 | 
					    $replace = name
 | 
				
			||||||
@@ -82,23 +94,22 @@ Dir.chdir(ROOT)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
if repo_old
 | 
					if repo_old
 | 
				
			||||||
  log "Deregistering: #{repo_old}"
 | 
					  log "Deregistering: #{repo_old}"
 | 
				
			||||||
  `git submodule deinit #{repo_old}`
 | 
					  command('git', 'submodule', 'deinit', repo_old)
 | 
				
			||||||
  `git rm -rf #{repo_old}`
 | 
					  command('git', 'rm', '-rf', repo_old)
 | 
				
			||||||
  `script/convert-grammars`
 | 
					  command('script/grammar-compiler', 'update', '-f')
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log "Registering new submodule: #{repo_new}"
 | 
					log "Registering new submodule: #{repo_new}"
 | 
				
			||||||
`git submodule add -f #{https} #{repo_new}`
 | 
					command('git', 'submodule', 'add', '-f', https, repo_new)
 | 
				
			||||||
exit 1 if $?.exitstatus > 0
 | 
					command('script/grammar-compiler', 'add', repo_new)
 | 
				
			||||||
`script/convert-grammars --add #{repo_new}`
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
log "Confirming license"
 | 
					log "Confirming license"
 | 
				
			||||||
if repo_old
 | 
					if repo_old
 | 
				
			||||||
  `script/licensed`
 | 
					  command('script/licensed')
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
  `script/licensed --module "#{repo_new}"`
 | 
					  command('script/licensed', '--module', repo_new)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log "Updating grammar documentation in vendor/README.md"
 | 
					log "Updating grammar documentation in vendor/README.md"
 | 
				
			||||||
`bundle exec rake samples`
 | 
					command('bundle', 'exec', 'rake', 'samples')
 | 
				
			||||||
`script/list-grammars`
 | 
					command('script/list-grammars')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,319 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env ruby
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
require 'bundler/setup'
 | 
					 | 
				
			||||||
require 'json'
 | 
					 | 
				
			||||||
require 'net/http'
 | 
					 | 
				
			||||||
require 'optparse'
 | 
					 | 
				
			||||||
require 'plist'
 | 
					 | 
				
			||||||
require 'set'
 | 
					 | 
				
			||||||
require 'thread'
 | 
					 | 
				
			||||||
require 'tmpdir'
 | 
					 | 
				
			||||||
require 'uri'
 | 
					 | 
				
			||||||
require 'yaml'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ROOT = File.expand_path("../..", __FILE__)
 | 
					 | 
				
			||||||
GRAMMARS_PATH = File.join(ROOT, "grammars")
 | 
					 | 
				
			||||||
SOURCES_FILE = File.join(ROOT, "grammars.yml")
 | 
					 | 
				
			||||||
CSONC = File.join(ROOT, "node_modules", ".bin", "csonc")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$options = {
 | 
					 | 
				
			||||||
  :add => false,
 | 
					 | 
				
			||||||
  :install => true,
 | 
					 | 
				
			||||||
  :output => SOURCES_FILE,
 | 
					 | 
				
			||||||
  :remote => true,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SingleFile
 | 
					 | 
				
			||||||
  def initialize(path)
 | 
					 | 
				
			||||||
    @path = path
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def url
 | 
					 | 
				
			||||||
    @path
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def fetch(tmp_dir)
 | 
					 | 
				
			||||||
    [@path]
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DirectoryPackage
 | 
					 | 
				
			||||||
  def self.fetch(dir)
 | 
					 | 
				
			||||||
    Dir["#{dir}/**/*"].select do |path|
 | 
					 | 
				
			||||||
      case File.extname(path.downcase)
 | 
					 | 
				
			||||||
      when '.plist'
 | 
					 | 
				
			||||||
        path.split('/')[-2] == 'Syntaxes'
 | 
					 | 
				
			||||||
      when '.tmlanguage', '.yaml-tmlanguage'
 | 
					 | 
				
			||||||
        true
 | 
					 | 
				
			||||||
      when '.cson', '.json'
 | 
					 | 
				
			||||||
        path.split('/')[-2] == 'grammars'
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        false
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def initialize(directory)
 | 
					 | 
				
			||||||
    @directory = directory
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def url
 | 
					 | 
				
			||||||
    @directory
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def fetch(tmp_dir)
 | 
					 | 
				
			||||||
    self.class.fetch(File.join(ROOT, @directory))
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class TarballPackage
 | 
					 | 
				
			||||||
  def self.fetch(tmp_dir, url)
 | 
					 | 
				
			||||||
    `curl --silent --location --max-time 30 --output "#{tmp_dir}/archive" "#{url}"`
 | 
					 | 
				
			||||||
    raise "Failed to fetch GH package: #{url} #{$?.to_s}" unless $?.success?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    output = File.join(tmp_dir, 'extracted')
 | 
					 | 
				
			||||||
    Dir.mkdir(output)
 | 
					 | 
				
			||||||
    `tar -C "#{output}" -xf "#{tmp_dir}/archive"`
 | 
					 | 
				
			||||||
    raise "Failed to uncompress tarball: #{tmp_dir}/archive (from #{url}) #{$?.to_s}" unless $?.success?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    DirectoryPackage.fetch(output)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  attr_reader :url
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def initialize(url)
 | 
					 | 
				
			||||||
    @url = url
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def fetch(tmp_dir)
 | 
					 | 
				
			||||||
    self.class.fetch(tmp_dir, url)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SingleGrammar
 | 
					 | 
				
			||||||
  attr_reader :url
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def initialize(url)
 | 
					 | 
				
			||||||
    @url = url
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def fetch(tmp_dir)
 | 
					 | 
				
			||||||
    filename = File.join(tmp_dir, File.basename(url))
 | 
					 | 
				
			||||||
    `curl --silent --location --max-time 10 --output "#{filename}" "#{url}"`
 | 
					 | 
				
			||||||
    raise "Failed to fetch grammar: #{url}: #{$?.to_s}" unless $?.success?
 | 
					 | 
				
			||||||
    [filename]
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SVNPackage
 | 
					 | 
				
			||||||
  attr_reader :url
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def initialize(url)
 | 
					 | 
				
			||||||
    @url = url
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def fetch(tmp_dir)
 | 
					 | 
				
			||||||
    `svn export -q "#{url}/Syntaxes" "#{tmp_dir}/Syntaxes"`
 | 
					 | 
				
			||||||
    raise "Failed to export SVN repository: #{url}: #{$?.to_s}" unless $?.success?
 | 
					 | 
				
			||||||
    Dir["#{tmp_dir}/Syntaxes/*.{plist,tmLanguage,tmlanguage,YAML-tmLanguage}"]
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class GitHubPackage
 | 
					 | 
				
			||||||
  def self.parse_url(url)
 | 
					 | 
				
			||||||
    url, ref = url.split("@", 2)
 | 
					 | 
				
			||||||
    path = URI.parse(url).path.split('/')
 | 
					 | 
				
			||||||
    [path[1], path[2].chomp('.git'), ref || "master"]
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  attr_reader :user
 | 
					 | 
				
			||||||
  attr_reader :repo
 | 
					 | 
				
			||||||
  attr_reader :ref
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def initialize(url)
 | 
					 | 
				
			||||||
    @user, @repo, @ref = self.class.parse_url(url)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def url
 | 
					 | 
				
			||||||
    suffix = "@#{ref}" unless ref == "master"
 | 
					 | 
				
			||||||
    "https://github.com/#{user}/#{repo}#{suffix}"
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def fetch(tmp_dir)
 | 
					 | 
				
			||||||
    url = "https://github.com/#{user}/#{repo}/archive/#{ref}.tar.gz"
 | 
					 | 
				
			||||||
    TarballPackage.fetch(tmp_dir, url)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def load_grammar(path)
 | 
					 | 
				
			||||||
  case File.extname(path.downcase)
 | 
					 | 
				
			||||||
  when '.plist', '.tmlanguage'
 | 
					 | 
				
			||||||
    Plist::parse_xml(path)
 | 
					 | 
				
			||||||
  when '.yaml-tmlanguage'
 | 
					 | 
				
			||||||
    content = File.read(path)
 | 
					 | 
				
			||||||
    # Attempt to parse YAML file even if it has a YAML 1.2 header
 | 
					 | 
				
			||||||
    if content.lines[0] =~ /^%YAML[ :]1\.2/
 | 
					 | 
				
			||||||
      content = content.lines[1..-1].join
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
    begin
 | 
					 | 
				
			||||||
      YAML.load(content)
 | 
					 | 
				
			||||||
    rescue Psych::SyntaxError => e
 | 
					 | 
				
			||||||
      $stderr.puts "Failed to parse YAML grammar '#{path}'"
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  when '.cson'
 | 
					 | 
				
			||||||
    cson = `"#{CSONC}" "#{path}"`
 | 
					 | 
				
			||||||
    raise "Failed to convert CSON grammar '#{path}': #{$?.to_s}" unless $?.success?
 | 
					 | 
				
			||||||
    JSON.parse(cson)
 | 
					 | 
				
			||||||
  when '.json'
 | 
					 | 
				
			||||||
    JSON.parse(File.read(path))
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    raise "Invalid document type #{path}"
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def load_grammars(tmp_dir, source, all_scopes)
 | 
					 | 
				
			||||||
  is_url = source.start_with?("http:", "https:")
 | 
					 | 
				
			||||||
  return [] if is_url && !$options[:remote]
 | 
					 | 
				
			||||||
  return [] if !is_url && !File.exist?(source)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  p = if !is_url
 | 
					 | 
				
			||||||
        if File.directory?(source)
 | 
					 | 
				
			||||||
          DirectoryPackage.new(source)
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          SingleFile.new(source)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      elsif source.end_with?('.tmLanguage', '.plist', '.YAML-tmLanguage')
 | 
					 | 
				
			||||||
        SingleGrammar.new(source)
 | 
					 | 
				
			||||||
      elsif source.start_with?('https://github.com')
 | 
					 | 
				
			||||||
        GitHubPackage.new(source)
 | 
					 | 
				
			||||||
      elsif source.start_with?('http://svn.textmate.org')
 | 
					 | 
				
			||||||
        SVNPackage.new(source)
 | 
					 | 
				
			||||||
      elsif source.end_with?('.tar.gz')
 | 
					 | 
				
			||||||
        TarballPackage.new(source)
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        nil
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  raise "Unsupported source: #{source}" unless p
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  p.fetch(tmp_dir).map do |path|
 | 
					 | 
				
			||||||
    grammar = load_grammar(path)
 | 
					 | 
				
			||||||
    scope = grammar['scopeName'] || grammar['scope']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if all_scopes.key?(scope)
 | 
					 | 
				
			||||||
      unless all_scopes[scope] == p.url
 | 
					 | 
				
			||||||
        $stderr.puts "WARN: Duplicated scope #{scope}\n" +
 | 
					 | 
				
			||||||
          "  Current package: #{p.url}\n" +
 | 
					 | 
				
			||||||
          "  Previous package: #{all_scopes[scope]}"
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
      next
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
    all_scopes[scope] = p.url
 | 
					 | 
				
			||||||
    grammar
 | 
					 | 
				
			||||||
  end.compact
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def install_grammars(grammars, path)
 | 
					 | 
				
			||||||
  installed = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  grammars.each do |grammar|
 | 
					 | 
				
			||||||
    scope = grammar['scopeName'] || grammar['scope']
 | 
					 | 
				
			||||||
    File.write(File.join(GRAMMARS_PATH, "#{scope}.json"), JSON.pretty_generate(grammar))
 | 
					 | 
				
			||||||
    installed << scope
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  $stderr.puts("OK #{path} (#{installed.join(', ')})")
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def run_thread(queue, all_scopes)
 | 
					 | 
				
			||||||
  Dir.mktmpdir do |tmpdir|
 | 
					 | 
				
			||||||
    loop do
 | 
					 | 
				
			||||||
      source, index = begin
 | 
					 | 
				
			||||||
        queue.pop(true)
 | 
					 | 
				
			||||||
      rescue ThreadError
 | 
					 | 
				
			||||||
        # The queue is empty.
 | 
					 | 
				
			||||||
        break
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      dir = "#{tmpdir}/#{index}"
 | 
					 | 
				
			||||||
      Dir.mkdir(dir)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      grammars = load_grammars(dir, source, all_scopes)
 | 
					 | 
				
			||||||
      install_grammars(grammars, source) if $options[:install]
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def generate_yaml(all_scopes, base)
 | 
					 | 
				
			||||||
  yaml = all_scopes.each_with_object(base) do |(key,value),out|
 | 
					 | 
				
			||||||
    out[value] ||= []
 | 
					 | 
				
			||||||
    out[value] << key
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  yaml = Hash[yaml.sort]
 | 
					 | 
				
			||||||
  yaml.each { |k, v| v.sort! }
 | 
					 | 
				
			||||||
  yaml
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def main(sources)
 | 
					 | 
				
			||||||
  begin
 | 
					 | 
				
			||||||
    Dir.mkdir(GRAMMARS_PATH)
 | 
					 | 
				
			||||||
  rescue Errno::EEXIST
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  `npm install`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  all_scopes = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if source = $options[:add]
 | 
					 | 
				
			||||||
    Dir.mktmpdir do |tmpdir|
 | 
					 | 
				
			||||||
      grammars = load_grammars(tmpdir, source, all_scopes)
 | 
					 | 
				
			||||||
      install_grammars(grammars, source) if $options[:install]
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
    generate_yaml(all_scopes, sources)
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    queue = Queue.new
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sources.each do |url, scopes|
 | 
					 | 
				
			||||||
      queue.push([url, queue.length])
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    threads = 8.times.map do
 | 
					 | 
				
			||||||
      Thread.new { run_thread(queue, all_scopes) }
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
    threads.each(&:join)
 | 
					 | 
				
			||||||
    generate_yaml(all_scopes, {})
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OptionParser.new do |opts|
 | 
					 | 
				
			||||||
  opts.banner = "Usage: #{$0} [options]"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  opts.on("--add GRAMMAR", "Add a new grammar. GRAMMAR may be a file path or URL.") do |a|
 | 
					 | 
				
			||||||
    $options[:add] = a
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  opts.on("--[no-]install", "Install grammars into grammars/ directory.") do |i|
 | 
					 | 
				
			||||||
    $options[:install] = i
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  opts.on("--output FILE", "Write output to FILE. Use - for stdout.") do |o|
 | 
					 | 
				
			||||||
    $options[:output] = o == "-" ? $stdout : o
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  opts.on("--[no-]remote", "Download remote grammars.") do |r|
 | 
					 | 
				
			||||||
    $options[:remote] = r
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end.parse!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sources = File.open(SOURCES_FILE) do |file|
 | 
					 | 
				
			||||||
  YAML.load(file)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
yaml = main(sources)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if $options[:output].is_a?(IO)
 | 
					 | 
				
			||||||
  $options[:output].write(YAML.dump(yaml))
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
  File.write($options[:output], YAML.dump(yaml))
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
							
								
								
									
										12
									
								
								script/grammar-compiler
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										12
									
								
								script/grammar-compiler
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set -e
 | 
				
			||||||
 | 
					cd "$(dirname "$0")/.."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					image="linguist/grammar-compiler:latest"
 | 
				
			||||||
 | 
					mkdir -p grammars
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exec docker run --rm \
 | 
				
			||||||
 | 
					    -u $(id -u $USER):$(id -g $USER) \
 | 
				
			||||||
 | 
					    -v $PWD:/src/linguist \
 | 
				
			||||||
 | 
					    -w /src/linguist $image "$@"
 | 
				
			||||||
@@ -1,60 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env ruby
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
require "bundler/setup"
 | 
					 | 
				
			||||||
require "json"
 | 
					 | 
				
			||||||
require "linguist"
 | 
					 | 
				
			||||||
require "set"
 | 
					 | 
				
			||||||
require "yaml"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ROOT = File.expand_path("../../", __FILE__)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def find_includes(json)
 | 
					 | 
				
			||||||
  case json
 | 
					 | 
				
			||||||
  when Hash
 | 
					 | 
				
			||||||
    result = []
 | 
					 | 
				
			||||||
    if inc = json["include"]
 | 
					 | 
				
			||||||
      result << inc.split("#", 2).first unless inc.start_with?("#", "$")
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
    result + json.values.flat_map { |v| find_includes(v) }
 | 
					 | 
				
			||||||
  when Array
 | 
					 | 
				
			||||||
    json.flat_map { |v| find_includes(v) }
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    []
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def transitive_includes(scope, includes)
 | 
					 | 
				
			||||||
  scopes = Set.new
 | 
					 | 
				
			||||||
  queue = includes[scope] || []
 | 
					 | 
				
			||||||
  while s = queue.shift
 | 
					 | 
				
			||||||
    next if scopes.include?(s)
 | 
					 | 
				
			||||||
    scopes << s
 | 
					 | 
				
			||||||
    queue += includes[s] || []
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
  scopes
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
includes = {}
 | 
					 | 
				
			||||||
Dir[File.join(ROOT, "grammars/*.json")].each do |path|
 | 
					 | 
				
			||||||
  scope = File.basename(path).sub(/\.json/, '')
 | 
					 | 
				
			||||||
  json = JSON.load(File.read(path))
 | 
					 | 
				
			||||||
  incs = find_includes(json)
 | 
					 | 
				
			||||||
  next if incs.empty?
 | 
					 | 
				
			||||||
  includes[scope] ||= []
 | 
					 | 
				
			||||||
  includes[scope] += incs
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
yaml = YAML.load(File.read(File.join(ROOT, "grammars.yml")))
 | 
					 | 
				
			||||||
language_scopes = Linguist::Language.all.map(&:tm_scope).to_set
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The set of used scopes is the scopes for each language, plus all the scopes
 | 
					 | 
				
			||||||
# they include, transitively.
 | 
					 | 
				
			||||||
used_scopes = language_scopes + language_scopes.flat_map { |s| transitive_includes(s, includes).to_a }.to_set
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unused = yaml.reject { |repo, scopes| scopes.any? { |scope| used_scopes.include?(scope) } }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
puts "Unused grammar repos"
 | 
					 | 
				
			||||||
puts unused.map { |repo, scopes| sprintf("%-100s %s", repo, scopes.join(", ")) }.sort.join("\n")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
yaml.delete_if { |k| unused.key?(k) }
 | 
					 | 
				
			||||||
File.write(File.join(ROOT, "grammars.yml"), YAML.dump(yaml))
 | 
					 | 
				
			||||||
							
								
								
									
										8
									
								
								test/fixtures/Perl/Module.pm
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								test/fixtures/Perl/Module.pm
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					use 5.006;
 | 
				
			||||||
 | 
					use strict;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=head1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=cut
 | 
				
			||||||
@@ -188,6 +188,17 @@ class TestFileBlob < Minitest::Test
 | 
				
			|||||||
    assert fixture_blob("Binary/MainMenu.nib").generated?
 | 
					    assert fixture_blob("Binary/MainMenu.nib").generated?
 | 
				
			||||||
    assert !sample_blob("XML/project.pbxproj").generated?
 | 
					    assert !sample_blob("XML/project.pbxproj").generated?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Cocoapods
 | 
				
			||||||
 | 
					    assert sample_blob('Pods/blah').generated?
 | 
				
			||||||
 | 
					    assert !sample_blob('My-Pods/blah').generated?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Carthage
 | 
				
			||||||
 | 
					    assert sample_blob('Carthage/Build/blah').generated?
 | 
				
			||||||
 | 
					    assert !sample_blob('Carthage/blah').generated?
 | 
				
			||||||
 | 
					    assert !sample_blob('Carthage/Checkout/blah').generated?
 | 
				
			||||||
 | 
					    assert !sample_blob('My-Carthage/Build/blah').generated?
 | 
				
			||||||
 | 
					    assert !sample_blob('My-Carthage/Build/blah').generated?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Gemfile.lock is NOT generated
 | 
					    # Gemfile.lock is NOT generated
 | 
				
			||||||
    assert !sample_blob("Gemfile.lock").generated?
 | 
					    assert !sample_blob("Gemfile.lock").generated?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -313,8 +324,6 @@ class TestFileBlob < Minitest::Test
 | 
				
			|||||||
    assert sample_blob("deps/http_parser/http_parser.c").vendored?
 | 
					    assert sample_blob("deps/http_parser/http_parser.c").vendored?
 | 
				
			||||||
    assert sample_blob("deps/v8/src/v8.h").vendored?
 | 
					    assert sample_blob("deps/v8/src/v8.h").vendored?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert sample_blob("tools/something/else.c").vendored?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Chart.js
 | 
					    # Chart.js
 | 
				
			||||||
    assert sample_blob("some/vendored/path/Chart.js").vendored?
 | 
					    assert sample_blob("some/vendored/path/Chart.js").vendored?
 | 
				
			||||||
    assert !sample_blob("some/vendored/path/chart.js").vendored?
 | 
					    assert !sample_blob("some/vendored/path/chart.js").vendored?
 | 
				
			||||||
@@ -490,9 +499,9 @@ class TestFileBlob < Minitest::Test
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Carthage
 | 
					    # Carthage
 | 
				
			||||||
    assert sample_blob('Carthage/blah').vendored?
 | 
					    assert sample_blob('Carthage/blah').vendored?
 | 
				
			||||||
 | 
					    assert sample_blob('iOS/Carthage/blah').vendored?
 | 
				
			||||||
    # Cocoapods
 | 
					    assert !sample_blob('My-Carthage/blah').vendored?
 | 
				
			||||||
    assert sample_blob('Pods/blah').vendored?
 | 
					    assert !sample_blob('iOS/My-Carthage/blah').vendored?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Html5shiv
 | 
					    # Html5shiv
 | 
				
			||||||
    assert sample_blob("Scripts/html5shiv.js").vendored?
 | 
					    assert sample_blob("Scripts/html5shiv.js").vendored?
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,6 +42,24 @@ class TestGenerated < Minitest::Test
 | 
				
			|||||||
    generated_sample_without_loading_data("Dummy/foo.xcworkspacedata")
 | 
					    generated_sample_without_loading_data("Dummy/foo.xcworkspacedata")
 | 
				
			||||||
    generated_sample_without_loading_data("Dummy/foo.xcuserstate")
 | 
					    generated_sample_without_loading_data("Dummy/foo.xcuserstate")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Cocoapods
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Pods/Pods.xcodeproj")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Pods/SwiftDependency/foo.swift")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Pods/ObjCDependency/foo.h")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Pods/ObjCDependency/foo.m")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Dummy/Pods/Pods.xcodeproj")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Dummy/Pods/SwiftDependency/foo.swift")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Dummy/Pods/ObjCDependency/foo.h")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Dummy/Pods/ObjCDependency/foo.m")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Carthage
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Carthage/Build/.Dependency.version")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Carthage/Build/iOS/Dependency.framework")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("Carthage/Build/Mac/Dependency.framework")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("src/Carthage/Build/.Dependency.version")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("src/Carthage/Build/iOS/Dependency.framework")
 | 
				
			||||||
 | 
					    generated_sample_without_loading_data("src/Carthage/Build/Mac/Dependency.framework")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Go-specific vendored paths
 | 
					    # Go-specific vendored paths
 | 
				
			||||||
    generated_sample_without_loading_data("go/vendor/github.com/foo.go")
 | 
					    generated_sample_without_loading_data("go/vendor/github.com/foo.go")
 | 
				
			||||||
    generated_sample_without_loading_data("go/vendor/golang.org/src/foo.c")
 | 
					    generated_sample_without_loading_data("go/vendor/golang.org/src/foo.c")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,6 @@ class TestGrammars < Minitest::Test
 | 
				
			|||||||
    "8653305b358375d0fced85dc24793b99919b11ef", # language-shellscript
 | 
					    "8653305b358375d0fced85dc24793b99919b11ef", # language-shellscript
 | 
				
			||||||
    "9f0c0b0926a18f5038e455e8df60221125fc3111", # elixir-tmbundle
 | 
					    "9f0c0b0926a18f5038e455e8df60221125fc3111", # elixir-tmbundle
 | 
				
			||||||
    "a4dadb2374282098c5b8b14df308906f5347d79a", # mako-tmbundle
 | 
					    "a4dadb2374282098c5b8b14df308906f5347d79a", # mako-tmbundle
 | 
				
			||||||
    "b9b24778619dce325b651f0d77cbc72e7ae0b0a3", # Julia.tmbundle
 | 
					 | 
				
			||||||
    "e06722add999e7428048abcc067cd85f1f7ca71c", # r.tmbundle
 | 
					    "e06722add999e7428048abcc067cd85f1f7ca71c", # r.tmbundle
 | 
				
			||||||
    "50b14a0e3f03d7ca754dac42ffb33302b5882b78", # smalltalk-tmbundle
 | 
					    "50b14a0e3f03d7ca754dac42ffb33302b5882b78", # smalltalk-tmbundle
 | 
				
			||||||
    "eafbc4a2f283752858e6908907f3c0c90188785b", # gap-tmbundle
 | 
					    "eafbc4a2f283752858e6908907f3c0c90188785b", # gap-tmbundle
 | 
				
			||||||
@@ -44,6 +43,7 @@ class TestGrammars < Minitest::Test
 | 
				
			|||||||
    "9dafd4e2a79cb13a6793b93877a254bc4d351e74", # sublime-text-ox
 | 
					    "9dafd4e2a79cb13a6793b93877a254bc4d351e74", # sublime-text-ox
 | 
				
			||||||
    "8e111741d97ba2e27b3d18a309d426b4a37e604f", # sublime-varnish
 | 
					    "8e111741d97ba2e27b3d18a309d426b4a37e604f", # sublime-varnish
 | 
				
			||||||
    "23d2538e33ce62d58abda2c039364b92f64ea6bc", # sublime-angelscript
 | 
					    "23d2538e33ce62d58abda2c039364b92f64ea6bc", # sublime-angelscript
 | 
				
			||||||
 | 
					    "53714285caad3c480ebd248c490509695d10404b", # atom-language-julia
 | 
				
			||||||
  ].freeze
 | 
					  ].freeze
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # List of allowed SPDX license names
 | 
					  # List of allowed SPDX license names
 | 
				
			||||||
@@ -94,19 +94,6 @@ class TestGrammars < Minitest::Test
 | 
				
			|||||||
    assert nonexistent_submodules.empty? && unlisted_submodules.empty?, message.sub(/\.\Z/, "")
 | 
					    assert nonexistent_submodules.empty? && unlisted_submodules.empty?, message.sub(/\.\Z/, "")
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def test_local_scopes_are_in_sync
 | 
					 | 
				
			||||||
    actual = YAML.load(`"#{File.join(ROOT, "script", "convert-grammars")}" --output - --no-install --no-remote`)
 | 
					 | 
				
			||||||
    assert $?.success?, "script/convert-grammars failed"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # We're not checking remote grammars. That can take a long time and make CI
 | 
					 | 
				
			||||||
    # flaky if network conditions are poor.
 | 
					 | 
				
			||||||
    @grammars.delete_if { |k, v| k.start_with?("http:", "https:") }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @grammars.each do |k, v|
 | 
					 | 
				
			||||||
      assert_equal v, actual[k], "The scopes listed for #{k} in grammars.yml don't match the scopes found in that repository"
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def test_readme_file_is_in_sync
 | 
					  def test_readme_file_is_in_sync
 | 
				
			||||||
    current_data = File.read("#{ROOT}/vendor/README.md").to_s.sub(/\A.+?<!--.+?-->\n/ms, "")
 | 
					    current_data = File.read("#{ROOT}/vendor/README.md").to_s.sub(/\A.+?<!--.+?-->\n/ms, "")
 | 
				
			||||||
    updated_data = `script/list-grammars --print`
 | 
					    updated_data = `script/list-grammars --print`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
require_relative "./helper"
 | 
					require_relative "./helper"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestHeuristcs < Minitest::Test
 | 
					class TestHeuristics < Minitest::Test
 | 
				
			||||||
  include Linguist
 | 
					  include Linguist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def fixture(name)
 | 
					  def fixture(name)
 | 
				
			||||||
@@ -237,14 +237,6 @@ class TestHeuristcs < Minitest::Test
 | 
				
			|||||||
    })
 | 
					    })
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Candidate languages = ["Pod", "Perl"]
 | 
					 | 
				
			||||||
  def test_pod_by_heuristics
 | 
					 | 
				
			||||||
    assert_heuristics({
 | 
					 | 
				
			||||||
      "Perl" => all_fixtures("Perl", "*.pod"),
 | 
					 | 
				
			||||||
      "Pod" => all_fixtures("Pod", "*.pod")
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Candidate languages = ["IDL", "Prolog", "QMake", "INI"]
 | 
					  # Candidate languages = ["IDL", "Prolog", "QMake", "INI"]
 | 
				
			||||||
  def test_pro_by_heuristics
 | 
					  def test_pro_by_heuristics
 | 
				
			||||||
    assert_heuristics({
 | 
					    assert_heuristics({
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -470,5 +470,7 @@ class TestLanguage < Minitest::Test
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  def test_non_crash_on_comma
 | 
					  def test_non_crash_on_comma
 | 
				
			||||||
    assert_nil Language[',']
 | 
					    assert_nil Language[',']
 | 
				
			||||||
 | 
					    assert_nil Language.find_by_name(',')
 | 
				
			||||||
 | 
					    assert_nil Language.find_by_alias(',')
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								tools/grammars/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tools/grammars/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					/vendor
 | 
				
			||||||
							
								
								
									
										35
									
								
								tools/grammars/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								tools/grammars/Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					FROM golang:1.9.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get update
 | 
				
			||||||
 | 
					RUN apt-get upgrade -y
 | 
				
			||||||
 | 
					RUN apt-get install -y curl gnupg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
 | 
				
			||||||
 | 
					RUN apt-get install -y nodejs
 | 
				
			||||||
 | 
					RUN npm install -g season
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get install -y cmake
 | 
				
			||||||
 | 
					RUN cd /tmp && git clone https://github.com/vmg/pcre
 | 
				
			||||||
 | 
					RUN mkdir -p /tmp/pcre/build && cd /tmp/pcre/build && \
 | 
				
			||||||
 | 
						cmake .. \
 | 
				
			||||||
 | 
							-DPCRE_SUPPORT_JIT=ON \
 | 
				
			||||||
 | 
							-DPCRE_SUPPORT_UTF=ON \
 | 
				
			||||||
 | 
							-DPCRE_SUPPORT_UNICODE_PROPERTIES=ON \
 | 
				
			||||||
 | 
							-DBUILD_SHARED_LIBS=OFF \
 | 
				
			||||||
 | 
							-DCMAKE_C_FLAGS="-fPIC $(EXTRA_PCRE_CFLAGS)" \
 | 
				
			||||||
 | 
							-DCMAKE_BUILD_TYPE=RelWithDebInfo \
 | 
				
			||||||
 | 
							-DPCRE_BUILD_PCRECPP=OFF \
 | 
				
			||||||
 | 
							-DPCRE_BUILD_PCREGREP=OFF \
 | 
				
			||||||
 | 
							-DPCRE_BUILD_TESTS=OFF \
 | 
				
			||||||
 | 
							-G "Unix Makefiles" && \
 | 
				
			||||||
 | 
					    make && make install
 | 
				
			||||||
 | 
					RUN rm -rf /tmp/pcre
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN go get -u github.com/golang/dep/cmd/dep
 | 
				
			||||||
 | 
					WORKDIR /go/src/github.com/github/linguist/tools/grammars
 | 
				
			||||||
 | 
					COPY . .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN dep ensure
 | 
				
			||||||
 | 
					RUN go install ./cmd/grammar-compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENTRYPOINT ["grammar-compiler"]
 | 
				
			||||||
							
								
								
									
										51
									
								
								tools/grammars/Gopkg.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								tools/grammars/Gopkg.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[projects]]
 | 
				
			||||||
 | 
					  branch = "master"
 | 
				
			||||||
 | 
					  name = "github.com/golang/protobuf"
 | 
				
			||||||
 | 
					  packages = ["proto"]
 | 
				
			||||||
 | 
					  revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[projects]]
 | 
				
			||||||
 | 
					  branch = "master"
 | 
				
			||||||
 | 
					  name = "github.com/groob/plist"
 | 
				
			||||||
 | 
					  packages = ["."]
 | 
				
			||||||
 | 
					  revision = "7b367e0aa692e62a223e823f3288c0c00f519a36"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[projects]]
 | 
				
			||||||
 | 
					  name = "github.com/mattn/go-runewidth"
 | 
				
			||||||
 | 
					  packages = ["."]
 | 
				
			||||||
 | 
					  revision = "9e777a8366cce605130a531d2cd6363d07ad7317"
 | 
				
			||||||
 | 
					  version = "v0.0.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[projects]]
 | 
				
			||||||
 | 
					  branch = "master"
 | 
				
			||||||
 | 
					  name = "github.com/mitchellh/mapstructure"
 | 
				
			||||||
 | 
					  packages = ["."]
 | 
				
			||||||
 | 
					  revision = "06020f85339e21b2478f756a78e295255ffa4d6a"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[projects]]
 | 
				
			||||||
 | 
					  name = "github.com/urfave/cli"
 | 
				
			||||||
 | 
					  packages = ["."]
 | 
				
			||||||
 | 
					  revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1"
 | 
				
			||||||
 | 
					  version = "v1.20.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[projects]]
 | 
				
			||||||
 | 
					  name = "gopkg.in/cheggaaa/pb.v1"
 | 
				
			||||||
 | 
					  packages = ["."]
 | 
				
			||||||
 | 
					  revision = "657164d0228d6bebe316fdf725c69f131a50fb10"
 | 
				
			||||||
 | 
					  version = "v1.0.18"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[projects]]
 | 
				
			||||||
 | 
					  branch = "v2"
 | 
				
			||||||
 | 
					  name = "gopkg.in/yaml.v2"
 | 
				
			||||||
 | 
					  packages = ["."]
 | 
				
			||||||
 | 
					  revision = "287cf08546ab5e7e37d55a84f7ed3fd1db036de5"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[solve-meta]
 | 
				
			||||||
 | 
					  analyzer-name = "dep"
 | 
				
			||||||
 | 
					  analyzer-version = 1
 | 
				
			||||||
 | 
					  inputs-digest = "ba2e3150d728692b49e3e2d652b6ea23db82777c340e0c432cd4af6f0eef9f55"
 | 
				
			||||||
 | 
					  solver-name = "gps-cdcl"
 | 
				
			||||||
 | 
					  solver-version = 1
 | 
				
			||||||
							
								
								
									
										23
									
								
								tools/grammars/Gopkg.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tools/grammars/Gopkg.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					[[constraint]]
 | 
				
			||||||
 | 
					  branch = "v2"
 | 
				
			||||||
 | 
					  name = "gopkg.in/yaml.v2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[constraint]]
 | 
				
			||||||
 | 
					  branch = "master"
 | 
				
			||||||
 | 
					  name = "github.com/groob/plist"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[constraint]]
 | 
				
			||||||
 | 
					  branch = "master"
 | 
				
			||||||
 | 
					  name = "github.com/golang/protobuf"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[constraint]]
 | 
				
			||||||
 | 
					  branch = "master"
 | 
				
			||||||
 | 
					  name = "github.com/mitchellh/mapstructure"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[constraint]]
 | 
				
			||||||
 | 
					  name = "gopkg.in/cheggaaa/pb.v1"
 | 
				
			||||||
 | 
					  version = "1.0.18"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[constraint]]
 | 
				
			||||||
 | 
					  name = "github.com/urfave/cli"
 | 
				
			||||||
 | 
					  version = "1.20.0"
 | 
				
			||||||
							
								
								
									
										120
									
								
								tools/grammars/cmd/grammar-compiler/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								tools/grammars/cmd/grammar-compiler/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/github/linguist/tools/grammars/compiler"
 | 
				
			||||||
 | 
						"github.com/urfave/cli"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func cwd() string {
 | 
				
			||||||
 | 
						cwd, _ := os.Getwd()
 | 
				
			||||||
 | 
						return cwd
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func wrap(err error) error {
 | 
				
			||||||
 | 
						return cli.NewExitError(err, 255)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
						app := cli.NewApp()
 | 
				
			||||||
 | 
						app.Name = "Linguist Grammars Compiler"
 | 
				
			||||||
 | 
						app.Usage = "Compile user-submitted grammars and check them for errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						app.Flags = []cli.Flag{
 | 
				
			||||||
 | 
							cli.StringFlag{
 | 
				
			||||||
 | 
								Name:  "linguist-path",
 | 
				
			||||||
 | 
								Value: cwd(),
 | 
				
			||||||
 | 
								Usage: "path to Linguist root",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						app.Commands = []cli.Command{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name:  "add",
 | 
				
			||||||
 | 
								Usage: "add a new grammar source",
 | 
				
			||||||
 | 
								Flags: []cli.Flag{
 | 
				
			||||||
 | 
									cli.BoolFlag{
 | 
				
			||||||
 | 
										Name:  "force, f",
 | 
				
			||||||
 | 
										Usage: "ignore compilation errors",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Action: func(c *cli.Context) error {
 | 
				
			||||||
 | 
									conv, err := compiler.NewConverter(c.String("linguist-path"))
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return wrap(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if err := conv.AddGrammar(c.Args().First()); err != nil {
 | 
				
			||||||
 | 
										if !c.Bool("force") {
 | 
				
			||||||
 | 
											return wrap(err)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if err := conv.WriteGrammarList(); err != nil {
 | 
				
			||||||
 | 
										return wrap(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return nil
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name:  "update",
 | 
				
			||||||
 | 
								Usage: "update grammars.yml with the contents of the grammars library",
 | 
				
			||||||
 | 
								Flags: []cli.Flag{
 | 
				
			||||||
 | 
									cli.BoolFlag{
 | 
				
			||||||
 | 
										Name:  "force, f",
 | 
				
			||||||
 | 
										Usage: "write grammars.yml even if grammars fail to compile",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Action: func(c *cli.Context) error {
 | 
				
			||||||
 | 
									conv, err := compiler.NewConverter(c.String("linguist-path"))
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return wrap(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if err := conv.ConvertGrammars(true); err != nil {
 | 
				
			||||||
 | 
										return wrap(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if err := conv.Report(); err != nil {
 | 
				
			||||||
 | 
										if !c.Bool("force") {
 | 
				
			||||||
 | 
											return wrap(err)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if err := conv.WriteGrammarList(); err != nil {
 | 
				
			||||||
 | 
										return wrap(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return nil
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name:  "compile",
 | 
				
			||||||
 | 
								Usage: "convert the grammars from the library",
 | 
				
			||||||
 | 
								Flags: []cli.Flag{
 | 
				
			||||||
 | 
									cli.StringFlag{Name: "proto-out, P"},
 | 
				
			||||||
 | 
									cli.StringFlag{Name: "out, o"},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Action: func(c *cli.Context) error {
 | 
				
			||||||
 | 
									conv, err := compiler.NewConverter(c.String("linguist-path"))
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return cli.NewExitError(err, 1)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if err := conv.ConvertGrammars(false); err != nil {
 | 
				
			||||||
 | 
										return cli.NewExitError(err, 1)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if out := c.String("proto-out"); out != "" {
 | 
				
			||||||
 | 
										if err := conv.WriteProto(out); err != nil {
 | 
				
			||||||
 | 
											return cli.NewExitError(err, 1)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if out := c.String("out"); out != "" {
 | 
				
			||||||
 | 
										if err := conv.WriteJSON(out); err != nil {
 | 
				
			||||||
 | 
											return cli.NewExitError(err, 1)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if err := conv.Report(); err != nil {
 | 
				
			||||||
 | 
										return wrap(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return nil
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						app.Run(os.Args)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										261
									
								
								tools/grammars/compiler/converter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								tools/grammars/compiler/converter.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,261 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"path"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grammar "github.com/github/linguist/tools/grammars/proto"
 | 
				
			||||||
 | 
						"github.com/golang/protobuf/proto"
 | 
				
			||||||
 | 
						pb "gopkg.in/cheggaaa/pb.v1"
 | 
				
			||||||
 | 
						yaml "gopkg.in/yaml.v2"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Converter struct {
 | 
				
			||||||
 | 
						root string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						modified bool
 | 
				
			||||||
 | 
						grammars map[string][]string
 | 
				
			||||||
 | 
						Loaded   map[string]*Repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						progress *pb.ProgressBar
 | 
				
			||||||
 | 
						wg       sync.WaitGroup
 | 
				
			||||||
 | 
						queue    chan string
 | 
				
			||||||
 | 
						mu       sync.Mutex
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) Load(src string) *Repository {
 | 
				
			||||||
 | 
						if strings.HasPrefix(src, "http://") || strings.HasPrefix(src, "https://") {
 | 
				
			||||||
 | 
							return LoadFromURL(src)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return LoadFromFilesystem(conv.root, src)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) work() {
 | 
				
			||||||
 | 
						for source := range conv.queue {
 | 
				
			||||||
 | 
							repo := conv.Load(source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							conv.mu.Lock()
 | 
				
			||||||
 | 
							conv.Loaded[source] = repo
 | 
				
			||||||
 | 
							conv.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							conv.progress.Increment()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						conv.wg.Done()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) tmpScopes() map[string]bool {
 | 
				
			||||||
 | 
						scopes := make(map[string]bool)
 | 
				
			||||||
 | 
						for _, ary := range conv.grammars {
 | 
				
			||||||
 | 
							for _, s := range ary {
 | 
				
			||||||
 | 
								scopes[s] = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return scopes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) AddGrammar(source string) error {
 | 
				
			||||||
 | 
						repo := conv.Load(source)
 | 
				
			||||||
 | 
						if len(repo.Files) == 0 {
 | 
				
			||||||
 | 
							return fmt.Errorf("source '%s' contains no grammar files", source)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						conv.grammars[source] = repo.Scopes()
 | 
				
			||||||
 | 
						conv.modified = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						knownScopes := conv.tmpScopes()
 | 
				
			||||||
 | 
						repo.FixRules(knownScopes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(repo.Errors) > 0 {
 | 
				
			||||||
 | 
							fmt.Fprintf(os.Stderr, "The new grammar %s contains %d errors:\n",
 | 
				
			||||||
 | 
								repo, len(repo.Errors))
 | 
				
			||||||
 | 
							for _, err := range repo.Errors {
 | 
				
			||||||
 | 
								fmt.Fprintf(os.Stderr, "    - %s\n", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							fmt.Fprintf(os.Stderr, "\n")
 | 
				
			||||||
 | 
							return fmt.Errorf("failed to compile the given grammar")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt.Printf("OK! added grammar source '%s'\n", source)
 | 
				
			||||||
 | 
						for scope := range repo.Files {
 | 
				
			||||||
 | 
							fmt.Printf("\tnew scope: %s\n", scope)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) AllScopes() map[string]bool {
 | 
				
			||||||
 | 
						// Map from scope -> Repository first to error check
 | 
				
			||||||
 | 
						// possible duplicates
 | 
				
			||||||
 | 
						allScopes := make(map[string]*Repository)
 | 
				
			||||||
 | 
						for _, repo := range conv.Loaded {
 | 
				
			||||||
 | 
							for scope := range repo.Files {
 | 
				
			||||||
 | 
								if original := allScopes[scope]; original != nil {
 | 
				
			||||||
 | 
									repo.Fail(&DuplicateScopeError{original, scope})
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									allScopes[scope] = repo
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Convert to scope -> bool
 | 
				
			||||||
 | 
						scopes := make(map[string]bool)
 | 
				
			||||||
 | 
						for s := range allScopes {
 | 
				
			||||||
 | 
							scopes[s] = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return scopes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) ConvertGrammars(update bool) error {
 | 
				
			||||||
 | 
						conv.Loaded = make(map[string]*Repository)
 | 
				
			||||||
 | 
						conv.queue = make(chan string, 128)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						conv.progress = pb.New(len(conv.grammars))
 | 
				
			||||||
 | 
						conv.progress.Start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i := 0; i < runtime.NumCPU(); i++ {
 | 
				
			||||||
 | 
							conv.wg.Add(1)
 | 
				
			||||||
 | 
							go conv.work()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for src := range conv.grammars {
 | 
				
			||||||
 | 
							conv.queue <- src
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						close(conv.queue)
 | 
				
			||||||
 | 
						conv.wg.Wait()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						done := fmt.Sprintf("done! processed %d grammars\n", len(conv.Loaded))
 | 
				
			||||||
 | 
						conv.progress.FinishPrint(done)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if update {
 | 
				
			||||||
 | 
							conv.grammars = make(map[string][]string)
 | 
				
			||||||
 | 
							conv.modified = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						knownScopes := conv.AllScopes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for source, repo := range conv.Loaded {
 | 
				
			||||||
 | 
							repo.FixRules(knownScopes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if update {
 | 
				
			||||||
 | 
								conv.grammars[source] = repo.Scopes()
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								expected := conv.grammars[source]
 | 
				
			||||||
 | 
								repo.CompareScopes(expected)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) WriteProto(path string) error {
 | 
				
			||||||
 | 
						library := grammar.Library{
 | 
				
			||||||
 | 
							Grammars: make(map[string]*grammar.Rule),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, repo := range conv.Loaded {
 | 
				
			||||||
 | 
							for scope, file := range repo.Files {
 | 
				
			||||||
 | 
								library.Grammars[scope] = file.Rule
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pb, err := proto.Marshal(&library)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ioutil.WriteFile(path, pb, 0666)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) writeJSONFile(path string, rule *grammar.Rule) error {
 | 
				
			||||||
 | 
						j, err := os.Create(path)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer j.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enc := json.NewEncoder(j)
 | 
				
			||||||
 | 
						enc.SetIndent("", "  ")
 | 
				
			||||||
 | 
						return enc.Encode(rule)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) WriteJSON(rulePath string) error {
 | 
				
			||||||
 | 
						if err := os.MkdirAll(rulePath, os.ModePerm); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, repo := range conv.Loaded {
 | 
				
			||||||
 | 
							for scope, file := range repo.Files {
 | 
				
			||||||
 | 
								p := path.Join(rulePath, scope+".json")
 | 
				
			||||||
 | 
								if err := conv.writeJSONFile(p, file.Rule); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) WriteGrammarList() error {
 | 
				
			||||||
 | 
						if !conv.modified {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						outyml, err := yaml.Marshal(conv.grammars)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ymlpath := path.Join(conv.root, "grammars.yml")
 | 
				
			||||||
 | 
						return ioutil.WriteFile(ymlpath, outyml, 0666)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (conv *Converter) Report() error {
 | 
				
			||||||
 | 
						var failed []*Repository
 | 
				
			||||||
 | 
						for _, repo := range conv.Loaded {
 | 
				
			||||||
 | 
							if len(repo.Errors) > 0 {
 | 
				
			||||||
 | 
								failed = append(failed, repo)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sort.Slice(failed, func(i, j int) bool {
 | 
				
			||||||
 | 
							return failed[i].Source < failed[j].Source
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						total := 0
 | 
				
			||||||
 | 
						for _, repo := range failed {
 | 
				
			||||||
 | 
							fmt.Fprintf(os.Stderr, "- [ ] %s (%d errors)\n", repo, len(repo.Errors))
 | 
				
			||||||
 | 
							for _, err := range repo.Errors {
 | 
				
			||||||
 | 
								fmt.Fprintf(os.Stderr, "    - [ ] %s\n", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							fmt.Fprintf(os.Stderr, "\n")
 | 
				
			||||||
 | 
							total += len(repo.Errors)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if total > 0 {
 | 
				
			||||||
 | 
							return fmt.Errorf("the grammar library contains %d errors", total)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewConverter(root string) (*Converter, error) {
 | 
				
			||||||
 | 
						yml, err := ioutil.ReadFile(path.Join(root, "grammars.yml"))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						conv := &Converter{root: root}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := yaml.Unmarshal(yml, &conv.grammars); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return conv, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								tools/grammars/compiler/cson.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								tools/grammars/compiler/cson.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"os/exec"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ConvertCSON(data []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						stdin := bytes.NewBuffer(data)
 | 
				
			||||||
 | 
						stdout := &bytes.Buffer{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd := exec.Command("csonc")
 | 
				
			||||||
 | 
						cmd.Stdin = stdin
 | 
				
			||||||
 | 
						cmd.Stdout = stdout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := cmd.Run(); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return stdout.Bytes(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								tools/grammars/compiler/data.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tools/grammars/compiler/data.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var GrammarAliases = map[string]string{
 | 
				
			||||||
 | 
						"source.erb":         "text.html.erb",
 | 
				
			||||||
 | 
						"source.cpp":         "source.c++",
 | 
				
			||||||
 | 
						"source.less":        "source.css.less",
 | 
				
			||||||
 | 
						"text.html.markdown": "source.gfm",
 | 
				
			||||||
 | 
						"text.md":            "source.gfm",
 | 
				
			||||||
 | 
						"source.php":         "text.html.php",
 | 
				
			||||||
 | 
						"text.plain":         "",
 | 
				
			||||||
 | 
						"source.asciidoc":    "text.html.asciidoc",
 | 
				
			||||||
 | 
						"source.perl6":       "source.perl6fe",
 | 
				
			||||||
 | 
						"source.css.scss":    "source.scss",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var KnownFields = map[string]bool{
 | 
				
			||||||
 | 
						"comment":            true,
 | 
				
			||||||
 | 
						"uuid":               true,
 | 
				
			||||||
 | 
						"author":             true,
 | 
				
			||||||
 | 
						"comments":           true,
 | 
				
			||||||
 | 
						"macros":             true,
 | 
				
			||||||
 | 
						"fileTypes":          true,
 | 
				
			||||||
 | 
						"firstLineMatch":     true,
 | 
				
			||||||
 | 
						"keyEquivalent":      true,
 | 
				
			||||||
 | 
						"foldingStopMarker":  true,
 | 
				
			||||||
 | 
						"foldingStartMarker": true,
 | 
				
			||||||
 | 
						"foldingEndMarker":   true,
 | 
				
			||||||
 | 
						"limitLineLength":    true,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										85
									
								
								tools/grammars/compiler/errors.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								tools/grammars/compiler/errors.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "fmt"
 | 
				
			||||||
 | 
					import "strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ConversionError struct {
 | 
				
			||||||
 | 
						Path string
 | 
				
			||||||
 | 
						Err  error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err *ConversionError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"Grammar conversion failed. File `%s` failed to parse: %s",
 | 
				
			||||||
 | 
							err.Path, err.Err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DuplicateScopeError struct {
 | 
				
			||||||
 | 
						Original  *Repository
 | 
				
			||||||
 | 
						Duplicate string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err *DuplicateScopeError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"Duplicate scope in repository: scope `%s` was already defined in %s",
 | 
				
			||||||
 | 
							err.Duplicate, err.Original)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type MissingScopeError struct {
 | 
				
			||||||
 | 
						Scope string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err *MissingScopeError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"Missing scope in repository: `%s` is listed in grammars.yml but cannot be found",
 | 
				
			||||||
 | 
							err.Scope)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UnexpectedScopeError struct {
 | 
				
			||||||
 | 
						File  *LoadedFile
 | 
				
			||||||
 | 
						Scope string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err *UnexpectedScopeError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"Unexpected scope in repository: `%s` declared in %s was not listed in grammars.yml",
 | 
				
			||||||
 | 
							err.Scope, err.File)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type MissingIncludeError struct {
 | 
				
			||||||
 | 
						File    *LoadedFile
 | 
				
			||||||
 | 
						Include string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err *MissingIncludeError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"Missing include in grammar: %s attempts to include `%s` but the scope cannot be found",
 | 
				
			||||||
 | 
							err.File, err.Include)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UnknownKeysError struct {
 | 
				
			||||||
 | 
						File *LoadedFile
 | 
				
			||||||
 | 
						Keys []string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err *UnknownKeysError) Error() string {
 | 
				
			||||||
 | 
						var keys []string
 | 
				
			||||||
 | 
						for _, k := range err.Keys {
 | 
				
			||||||
 | 
							keys = append(keys, fmt.Sprintf("`%s`", k))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"Unknown keys in grammar: %s contains invalid keys (%s)",
 | 
				
			||||||
 | 
							err.File, strings.Join(keys, ", "))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InvalidRegexError struct {
 | 
				
			||||||
 | 
						File *LoadedFile
 | 
				
			||||||
 | 
						Err  error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err *InvalidRegexError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"Invalid regex in grammar: %s contains a malformed regex (%s)",
 | 
				
			||||||
 | 
							err.File, err.Err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										124
									
								
								tools/grammars/compiler/loader.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								tools/grammars/compiler/loader.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grammar "github.com/github/linguist/tools/grammars/proto"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type LoadedFile struct {
 | 
				
			||||||
 | 
						Path string
 | 
				
			||||||
 | 
						Rule *grammar.Rule
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (f *LoadedFile) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("`%s` (in `%s`)", f.Rule.ScopeName, f.Path)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Repository struct {
 | 
				
			||||||
 | 
						Source   string
 | 
				
			||||||
 | 
						Upstream string
 | 
				
			||||||
 | 
						Files    map[string]*LoadedFile
 | 
				
			||||||
 | 
						Errors   []error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newRepository(src string) *Repository {
 | 
				
			||||||
 | 
						return &Repository{
 | 
				
			||||||
 | 
							Source: src,
 | 
				
			||||||
 | 
							Files:  make(map[string]*LoadedFile),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (repo *Repository) String() string {
 | 
				
			||||||
 | 
						str := fmt.Sprintf("repository `%s`", repo.Source)
 | 
				
			||||||
 | 
						if repo.Upstream != "" {
 | 
				
			||||||
 | 
							str = str + fmt.Sprintf(" (from %s)", repo.Upstream)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return str
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (repo *Repository) Fail(err error) {
 | 
				
			||||||
 | 
						repo.Errors = append(repo.Errors, err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (repo *Repository) AddFile(path string, rule *grammar.Rule, uk []string) {
 | 
				
			||||||
 | 
						file := &LoadedFile{
 | 
				
			||||||
 | 
							Path: path,
 | 
				
			||||||
 | 
							Rule: rule,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						repo.Files[rule.ScopeName] = file
 | 
				
			||||||
 | 
						if len(uk) > 0 {
 | 
				
			||||||
 | 
							repo.Fail(&UnknownKeysError{file, uk})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func toMap(slice []string) map[string]bool {
 | 
				
			||||||
 | 
						m := make(map[string]bool)
 | 
				
			||||||
 | 
						for _, s := range slice {
 | 
				
			||||||
 | 
							m[s] = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return m
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (repo *Repository) CompareScopes(scopes []string) {
 | 
				
			||||||
 | 
						expected := toMap(scopes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for scope, file := range repo.Files {
 | 
				
			||||||
 | 
							if !expected[scope] {
 | 
				
			||||||
 | 
								repo.Fail(&UnexpectedScopeError{file, scope})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for scope := range expected {
 | 
				
			||||||
 | 
							if _, ok := repo.Files[scope]; !ok {
 | 
				
			||||||
 | 
								repo.Fail(&MissingScopeError{scope})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (repo *Repository) FixRules(knownScopes map[string]bool) {
 | 
				
			||||||
 | 
						for _, file := range repo.Files {
 | 
				
			||||||
 | 
							w := walker{
 | 
				
			||||||
 | 
								File:    file,
 | 
				
			||||||
 | 
								Known:   knownScopes,
 | 
				
			||||||
 | 
								Missing: make(map[string]bool),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							w.walk(file.Rule)
 | 
				
			||||||
 | 
							repo.Errors = append(repo.Errors, w.Errors...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (repo *Repository) Scopes() (scopes []string) {
 | 
				
			||||||
 | 
						for s := range repo.Files {
 | 
				
			||||||
 | 
							scopes = append(scopes, s)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sort.Strings(scopes)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func isValidGrammar(path string, info os.FileInfo) bool {
 | 
				
			||||||
 | 
						if info.IsDir() {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dir := filepath.Dir(path)
 | 
				
			||||||
 | 
						ext := filepath.Ext(path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch strings.ToLower(ext) {
 | 
				
			||||||
 | 
						case ".plist":
 | 
				
			||||||
 | 
							return strings.HasSuffix(dir, "/Syntaxes")
 | 
				
			||||||
 | 
						case ".tmlanguage", ".yaml-tmlanguage":
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						case ".cson", ".json":
 | 
				
			||||||
 | 
							return strings.HasSuffix(dir, "/grammars")
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										80
									
								
								tools/grammars/compiler/loader_fs.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								tools/grammars/compiler/loader_fs.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"os/exec"
 | 
				
			||||||
 | 
						"path"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type fsLoader struct {
 | 
				
			||||||
 | 
						*Repository
 | 
				
			||||||
 | 
						abspath string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (l *fsLoader) findGrammars() (files []string, err error) {
 | 
				
			||||||
 | 
						err = filepath.Walk(l.abspath,
 | 
				
			||||||
 | 
							func(path string, info os.FileInfo, err error) error {
 | 
				
			||||||
 | 
								if err == nil && isValidGrammar(path, info) {
 | 
				
			||||||
 | 
									files = append(files, path)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (l *fsLoader) load() {
 | 
				
			||||||
 | 
						grammars, err := l.findGrammars()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							l.Fail(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, path := range grammars {
 | 
				
			||||||
 | 
							data, err := ioutil.ReadFile(path)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								l.Fail(err)
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if rel, err := filepath.Rel(l.abspath, path); err == nil {
 | 
				
			||||||
 | 
								path = rel
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rule, unknown, err := ConvertProto(filepath.Ext(path), data)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								l.Fail(&ConversionError{path, err})
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if _, ok := l.Files[rule.ScopeName]; ok {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							l.AddFile(path, rule, unknown)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func gitRemoteName(path string) (string, error) {
 | 
				
			||||||
 | 
						remote, err := exec.Command("git", "-C", path, "remote", "get-url", "origin").Output()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return strings.TrimSpace(string(remote)), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LoadFromFilesystem(root, src string) *Repository {
 | 
				
			||||||
 | 
						loader := fsLoader{
 | 
				
			||||||
 | 
							Repository: newRepository(src),
 | 
				
			||||||
 | 
							abspath:    path.Join(root, src),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						loader.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ups, err := gitRemoteName(loader.abspath); err == nil {
 | 
				
			||||||
 | 
							loader.Repository.Upstream = ups
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return loader.Repository
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										93
									
								
								tools/grammars/compiler/loader_url.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								tools/grammars/compiler/loader_url.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"archive/tar"
 | 
				
			||||||
 | 
						"compress/gzip"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type urlLoader struct {
 | 
				
			||||||
 | 
						*Repository
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (l *urlLoader) loadTarball(r io.Reader) {
 | 
				
			||||||
 | 
						gzf, err := gzip.NewReader(r)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							l.Fail(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer gzf.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tarReader := tar.NewReader(gzf)
 | 
				
			||||||
 | 
						for true {
 | 
				
			||||||
 | 
							header, err := tarReader.Next()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if err != io.EOF {
 | 
				
			||||||
 | 
									l.Fail(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if isValidGrammar(header.Name, header.FileInfo()) {
 | 
				
			||||||
 | 
								data, err := ioutil.ReadAll(tarReader)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									l.Fail(err)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ext := filepath.Ext(header.Name)
 | 
				
			||||||
 | 
								rule, unknown, err := ConvertProto(ext, data)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									l.Fail(&ConversionError{header.Name, err})
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if _, ok := l.Files[rule.ScopeName]; ok {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								l.AddFile(header.Name, rule, unknown)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (l *urlLoader) load() {
 | 
				
			||||||
 | 
						res, err := http.Get(l.Source)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							l.Fail(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer res.Body.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if strings.HasSuffix(l.Source, ".tar.gz") {
 | 
				
			||||||
 | 
							l.loadTarball(res.Body)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data, err := ioutil.ReadAll(res.Body)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							l.Fail(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ext := filepath.Ext(l.Source)
 | 
				
			||||||
 | 
						filename := filepath.Base(l.Source)
 | 
				
			||||||
 | 
						rule, unknown, err := ConvertProto(ext, data)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							l.Fail(&ConversionError{filename, err})
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						l.AddFile(filename, rule, unknown)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LoadFromURL(src string) *Repository {
 | 
				
			||||||
 | 
						loader := urlLoader{newRepository(src)}
 | 
				
			||||||
 | 
						loader.load()
 | 
				
			||||||
 | 
						return loader.Repository
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										68
									
								
								tools/grammars/compiler/pcre.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								tools/grammars/compiler/pcre.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/github/linguist/tools/grammars/pcre"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type replacement struct {
 | 
				
			||||||
 | 
						pos int
 | 
				
			||||||
 | 
						len int
 | 
				
			||||||
 | 
						val string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func fixRegex(re string) (string, bool) {
 | 
				
			||||||
 | 
						var (
 | 
				
			||||||
 | 
							replace     []replacement
 | 
				
			||||||
 | 
							escape      = false
 | 
				
			||||||
 | 
							hasBackRefs = false
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, ch := range re {
 | 
				
			||||||
 | 
							if escape {
 | 
				
			||||||
 | 
								if ch == 'h' {
 | 
				
			||||||
 | 
									replace = append(replace, replacement{i - 1, 2, "[[:xdigit:]]"})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if '0' <= ch && ch <= '9' {
 | 
				
			||||||
 | 
									hasBackRefs = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							escape = !escape && ch == '\\'
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(replace) > 0 {
 | 
				
			||||||
 | 
							reb := []byte(re)
 | 
				
			||||||
 | 
							offset := 0
 | 
				
			||||||
 | 
							for _, repl := range replace {
 | 
				
			||||||
 | 
								reb = append(
 | 
				
			||||||
 | 
									reb[:offset+repl.pos],
 | 
				
			||||||
 | 
									append([]byte(repl.val), reb[offset+repl.pos+repl.len:]...)...)
 | 
				
			||||||
 | 
								offset += len(repl.val) - repl.len
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return string(reb), hasBackRefs
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return re, hasBackRefs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CheckPCRE(re string) (string, error) {
 | 
				
			||||||
 | 
						hasBackRefs := false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if re == "" {
 | 
				
			||||||
 | 
							return "", nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(re) > 32*1024 {
 | 
				
			||||||
 | 
							return "", fmt.Errorf(
 | 
				
			||||||
 | 
								"regex %s: definition too long (%d bytes)",
 | 
				
			||||||
 | 
								pcre.RegexPP(re), len(re))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						re, hasBackRefs = fixRegex(re)
 | 
				
			||||||
 | 
						if !hasBackRefs {
 | 
				
			||||||
 | 
							if err := pcre.CheckRegexp(re, pcre.DefaultFlags); err != nil {
 | 
				
			||||||
 | 
								return "", err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return re, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								tools/grammars/compiler/pcre_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								tools/grammars/compiler/pcre_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Test_fixRegex(t *testing.T) {
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							re   string
 | 
				
			||||||
 | 
							want string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{"foobar", "foobar"},
 | 
				
			||||||
 | 
							{`testing\h`, "testing[[:xdigit:]]"},
 | 
				
			||||||
 | 
							{`\htest`, `[[:xdigit:]]test`},
 | 
				
			||||||
 | 
							{`abc\hdef`, `abc[[:xdigit:]]def`},
 | 
				
			||||||
 | 
							{`\\\htest`, `\\[[:xdigit:]]test`},
 | 
				
			||||||
 | 
							{`\\htest`, `\\htest`},
 | 
				
			||||||
 | 
							{`\h\h\h\h`, `[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]`},
 | 
				
			||||||
 | 
							{`abc\hdef\hghi\h`, `abc[[:xdigit:]]def[[:xdigit:]]ghi[[:xdigit:]]`},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							got, _ := fixRegex(tt.re)
 | 
				
			||||||
 | 
							if got != tt.want {
 | 
				
			||||||
 | 
								t.Errorf("fixRegex() got = %v, want %v", got, tt.want)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										96
									
								
								tools/grammars/compiler/proto.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								tools/grammars/compiler/proto.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grammar "github.com/github/linguist/tools/grammars/proto"
 | 
				
			||||||
 | 
						"github.com/groob/plist"
 | 
				
			||||||
 | 
						"github.com/mitchellh/mapstructure"
 | 
				
			||||||
 | 
						yaml "gopkg.in/yaml.v2"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func looseDecoder(f reflect.Kind, t reflect.Kind, data interface{}) (interface{}, error) {
 | 
				
			||||||
 | 
						dataVal := reflect.ValueOf(data)
 | 
				
			||||||
 | 
						switch t {
 | 
				
			||||||
 | 
						case reflect.Bool:
 | 
				
			||||||
 | 
							switch f {
 | 
				
			||||||
 | 
							case reflect.Bool:
 | 
				
			||||||
 | 
								return dataVal.Bool(), nil
 | 
				
			||||||
 | 
							case reflect.Float32, reflect.Float64:
 | 
				
			||||||
 | 
								return (int(dataVal.Float()) != 0), nil
 | 
				
			||||||
 | 
							case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 | 
				
			||||||
 | 
								return (dataVal.Int() != 0), nil
 | 
				
			||||||
 | 
							case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
 | 
				
			||||||
 | 
								return (dataVal.Uint() != 0), nil
 | 
				
			||||||
 | 
							case reflect.String:
 | 
				
			||||||
 | 
								switch dataVal.String() {
 | 
				
			||||||
 | 
								case "1":
 | 
				
			||||||
 | 
									return true, nil
 | 
				
			||||||
 | 
								case "0":
 | 
				
			||||||
 | 
									return false, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return data, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func filterUnusedKeys(keys []string) (out []string) {
 | 
				
			||||||
 | 
						for _, k := range keys {
 | 
				
			||||||
 | 
							parts := strings.Split(k, ".")
 | 
				
			||||||
 | 
							field := parts[len(parts)-1]
 | 
				
			||||||
 | 
							if !KnownFields[field] {
 | 
				
			||||||
 | 
								out = append(out, k)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ConvertProto(ext string, data []byte) (*grammar.Rule, []string, error) {
 | 
				
			||||||
 | 
						var (
 | 
				
			||||||
 | 
							raw map[string]interface{}
 | 
				
			||||||
 | 
							out grammar.Rule
 | 
				
			||||||
 | 
							err error
 | 
				
			||||||
 | 
							md  mapstructure.Metadata
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch strings.ToLower(ext) {
 | 
				
			||||||
 | 
						case ".plist", ".tmlanguage":
 | 
				
			||||||
 | 
							err = plist.Unmarshal(data, &raw)
 | 
				
			||||||
 | 
						case ".yaml-tmlanguage":
 | 
				
			||||||
 | 
							err = yaml.Unmarshal(data, &raw)
 | 
				
			||||||
 | 
						case ".cson":
 | 
				
			||||||
 | 
							data, err = ConvertCSON(data)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								err = json.Unmarshal(data, &raw)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case ".json":
 | 
				
			||||||
 | 
							err = json.Unmarshal(data, &raw)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							err = fmt.Errorf("grammars: unsupported extension '%s'", ext)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config := mapstructure.DecoderConfig{
 | 
				
			||||||
 | 
							Result:     &out,
 | 
				
			||||||
 | 
							Metadata:   &md,
 | 
				
			||||||
 | 
							DecodeHook: looseDecoder,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						decoder, err := mapstructure.NewDecoder(&config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := decoder.Decode(raw); err != nil {
 | 
				
			||||||
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &out, filterUnusedKeys(md.Unused), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										79
									
								
								tools/grammars/compiler/walker.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								tools/grammars/compiler/walker.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					package compiler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grammar "github.com/github/linguist/tools/grammars/proto"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *walker) checkInclude(rule *grammar.Rule) {
 | 
				
			||||||
 | 
						include := rule.Include
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if include == "" || include[0] == '#' || include[0] == '$' {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if alias, ok := GrammarAliases[include]; ok {
 | 
				
			||||||
 | 
							rule.Include = alias
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						include = strings.Split(include, "#")[0]
 | 
				
			||||||
 | 
						ok := w.Known[include]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							if !w.Missing[include] {
 | 
				
			||||||
 | 
								w.Missing[include] = true
 | 
				
			||||||
 | 
								w.Errors = append(w.Errors, &MissingIncludeError{w.File, include})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							rule.Include = ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *walker) checkRegexps(rule *grammar.Rule) {
 | 
				
			||||||
 | 
						check := func(re string) string {
 | 
				
			||||||
 | 
							re2, err := CheckPCRE(re)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								w.Errors = append(w.Errors, &InvalidRegexError{w.File, err})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return re2
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rule.Match = check(rule.Match)
 | 
				
			||||||
 | 
						rule.Begin = check(rule.Begin)
 | 
				
			||||||
 | 
						rule.While = check(rule.While)
 | 
				
			||||||
 | 
						rule.End = check(rule.End)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *walker) walk(rule *grammar.Rule) {
 | 
				
			||||||
 | 
						w.checkInclude(rule)
 | 
				
			||||||
 | 
						w.checkRegexps(rule)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, rule := range rule.Patterns {
 | 
				
			||||||
 | 
							w.walk(rule)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, rule := range rule.Captures {
 | 
				
			||||||
 | 
							w.walk(rule)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, rule := range rule.BeginCaptures {
 | 
				
			||||||
 | 
							w.walk(rule)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, rule := range rule.WhileCaptures {
 | 
				
			||||||
 | 
							w.walk(rule)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, rule := range rule.EndCaptures {
 | 
				
			||||||
 | 
							w.walk(rule)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, rule := range rule.Repository {
 | 
				
			||||||
 | 
							w.walk(rule)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, rule := range rule.Injections {
 | 
				
			||||||
 | 
							w.walk(rule)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type walker struct {
 | 
				
			||||||
 | 
						File    *LoadedFile
 | 
				
			||||||
 | 
						Known   map[string]bool
 | 
				
			||||||
 | 
						Missing map[string]bool
 | 
				
			||||||
 | 
						Errors  []error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								tools/grammars/docker/build
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										11
									
								
								tools/grammars/docker/build
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set -ex
 | 
				
			||||||
 | 
					cd "$(dirname "$0")/.."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					image=linguist/grammar-compiler
 | 
				
			||||||
 | 
					docker build -t $image .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "$1" = "--push" ]; then
 | 
				
			||||||
 | 
					    docker push $image
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
							
								
								
									
										53
									
								
								tools/grammars/pcre/pcre.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tools/grammars/pcre/pcre.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					package pcre
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					#cgo LDFLAGS: -lpcre
 | 
				
			||||||
 | 
					#include <pcre.h>
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					import "C"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"unsafe"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RegexPP(re string) string {
 | 
				
			||||||
 | 
						if len(re) > 32 {
 | 
				
			||||||
 | 
							re = fmt.Sprintf("\"`%s`...\"", re[:32])
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							re = fmt.Sprintf("\"`%s`\"", re)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return strings.Replace(re, "\n", "", -1)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CompileError struct {
 | 
				
			||||||
 | 
						Pattern string
 | 
				
			||||||
 | 
						Message string
 | 
				
			||||||
 | 
						Offset  int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *CompileError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("regex %s: %s (at offset %d)",
 | 
				
			||||||
 | 
							RegexPP(e.Pattern), e.Message, e.Offset)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DefaultFlags = int(C.PCRE_DUPNAMES | C.PCRE_UTF8 | C.PCRE_NEWLINE_ANYCRLF)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CheckRegexp(pattern string, flags int) error {
 | 
				
			||||||
 | 
						pattern1 := C.CString(pattern)
 | 
				
			||||||
 | 
						defer C.free(unsafe.Pointer(pattern1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var errptr *C.char
 | 
				
			||||||
 | 
						var erroffset C.int
 | 
				
			||||||
 | 
						ptr := C.pcre_compile(pattern1, C.int(flags), &errptr, &erroffset, nil)
 | 
				
			||||||
 | 
						if ptr == nil {
 | 
				
			||||||
 | 
							return &CompileError{
 | 
				
			||||||
 | 
								Pattern: pattern,
 | 
				
			||||||
 | 
								Message: C.GoString(errptr),
 | 
				
			||||||
 | 
								Offset:  int(erroffset),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						C.free(unsafe.Pointer(ptr))
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										239
									
								
								tools/grammars/proto/grammar.pb.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								tools/grammars/proto/grammar.pb.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,239 @@
 | 
				
			|||||||
 | 
					// Code generated by protoc-gen-go. DO NOT EDIT.
 | 
				
			||||||
 | 
					// source: proto/grammar.proto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Package grammar is a generated protocol buffer package.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is generated from these files:
 | 
				
			||||||
 | 
						proto/grammar.proto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It has these top-level messages:
 | 
				
			||||||
 | 
						Rule
 | 
				
			||||||
 | 
						Library
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					package grammar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import proto "github.com/golang/protobuf/proto"
 | 
				
			||||||
 | 
					import fmt "fmt"
 | 
				
			||||||
 | 
					import math "math"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Reference imports to suppress errors if they are not otherwise used.
 | 
				
			||||||
 | 
					var _ = proto.Marshal
 | 
				
			||||||
 | 
					var _ = fmt.Errorf
 | 
				
			||||||
 | 
					var _ = math.Inf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This is a compile-time assertion to ensure that this generated file
 | 
				
			||||||
 | 
					// is compatible with the proto package it is being compiled against.
 | 
				
			||||||
 | 
					// A compilation error at this line likely means your copy of the
 | 
				
			||||||
 | 
					// proto package needs to be updated.
 | 
				
			||||||
 | 
					const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Rule struct {
 | 
				
			||||||
 | 
						Name                string           `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
 | 
				
			||||||
 | 
						ScopeName           string           `protobuf:"bytes,2,opt,name=scopeName" json:"scopeName,omitempty"`
 | 
				
			||||||
 | 
						ContentName         string           `protobuf:"bytes,3,opt,name=contentName" json:"contentName,omitempty"`
 | 
				
			||||||
 | 
						Match               string           `protobuf:"bytes,4,opt,name=match" json:"match,omitempty"`
 | 
				
			||||||
 | 
						Begin               string           `protobuf:"bytes,5,opt,name=begin" json:"begin,omitempty"`
 | 
				
			||||||
 | 
						While               string           `protobuf:"bytes,6,opt,name=while" json:"while,omitempty"`
 | 
				
			||||||
 | 
						End                 string           `protobuf:"bytes,7,opt,name=end" json:"end,omitempty"`
 | 
				
			||||||
 | 
						Include             string           `protobuf:"bytes,8,opt,name=include" json:"include,omitempty"`
 | 
				
			||||||
 | 
						Patterns            []*Rule          `protobuf:"bytes,9,rep,name=patterns" json:"patterns,omitempty"`
 | 
				
			||||||
 | 
						Captures            map[string]*Rule `protobuf:"bytes,10,rep,name=captures" json:"captures,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 | 
				
			||||||
 | 
						BeginCaptures       map[string]*Rule `protobuf:"bytes,11,rep,name=beginCaptures" json:"beginCaptures,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 | 
				
			||||||
 | 
						WhileCaptures       map[string]*Rule `protobuf:"bytes,12,rep,name=whileCaptures" json:"whileCaptures,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 | 
				
			||||||
 | 
						EndCaptures         map[string]*Rule `protobuf:"bytes,13,rep,name=endCaptures" json:"endCaptures,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 | 
				
			||||||
 | 
						Repository          map[string]*Rule `protobuf:"bytes,14,rep,name=repository" json:"repository,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 | 
				
			||||||
 | 
						Injections          map[string]*Rule `protobuf:"bytes,15,rep,name=injections" json:"injections,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 | 
				
			||||||
 | 
						Disabled            bool             `protobuf:"varint,16,opt,name=disabled" json:"disabled,omitempty"`
 | 
				
			||||||
 | 
						ApplyEndPatternLast bool             `protobuf:"varint,17,opt,name=applyEndPatternLast" json:"applyEndPatternLast,omitempty"`
 | 
				
			||||||
 | 
						IncludeResetBase    bool             `protobuf:"varint,18,opt,name=includeResetBase" json:"includeResetBase,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) Reset()                    { *m = Rule{} }
 | 
				
			||||||
 | 
					func (m *Rule) String() string            { return proto.CompactTextString(m) }
 | 
				
			||||||
 | 
					func (*Rule) ProtoMessage()               {}
 | 
				
			||||||
 | 
					func (*Rule) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetName() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetScopeName() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ScopeName
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetContentName() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ContentName
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetMatch() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Match
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetBegin() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Begin
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetWhile() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.While
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetEnd() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.End
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetInclude() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Include
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetPatterns() []*Rule {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Patterns
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetCaptures() map[string]*Rule {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Captures
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetBeginCaptures() map[string]*Rule {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.BeginCaptures
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetWhileCaptures() map[string]*Rule {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.WhileCaptures
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetEndCaptures() map[string]*Rule {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.EndCaptures
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetRepository() map[string]*Rule {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Repository
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetInjections() map[string]*Rule {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Injections
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetDisabled() bool {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Disabled
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetApplyEndPatternLast() bool {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ApplyEndPatternLast
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Rule) GetIncludeResetBase() bool {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.IncludeResetBase
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Library struct {
 | 
				
			||||||
 | 
						Grammars map[string]*Rule `protobuf:"bytes,1,rep,name=grammars" json:"grammars,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Library) Reset()                    { *m = Library{} }
 | 
				
			||||||
 | 
					func (m *Library) String() string            { return proto.CompactTextString(m) }
 | 
				
			||||||
 | 
					func (*Library) ProtoMessage()               {}
 | 
				
			||||||
 | 
					func (*Library) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Library) GetGrammars() map[string]*Rule {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Grammars
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						proto.RegisterType((*Rule)(nil), "grammar.Rule")
 | 
				
			||||||
 | 
						proto.RegisterType((*Library)(nil), "grammar.Library")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() { proto.RegisterFile("proto/grammar.proto", fileDescriptor0) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var fileDescriptor0 = []byte{
 | 
				
			||||||
 | 
						// 486 bytes of a gzipped FileDescriptorProto
 | 
				
			||||||
 | 
						0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcb, 0x8e, 0xd3, 0x30,
 | 
				
			||||||
 | 
						0x14, 0x55, 0x66, 0xda, 0x69, 0x7a, 0x4b, 0x99, 0x72, 0x87, 0x85, 0x55, 0x1e, 0x8a, 0x86, 0x4d,
 | 
				
			||||||
 | 
						0x61, 0x51, 0x10, 0x2c, 0x40, 0x23, 0x21, 0xa1, 0x41, 0x05, 0x81, 0xca, 0x43, 0xd9, 0xb0, 0x76,
 | 
				
			||||||
 | 
						0x13, 0x6b, 0x26, 0x90, 0x3a, 0x91, 0xed, 0x82, 0xf2, 0x19, 0x7c, 0x19, 0xbf, 0x84, 0x7c, 0xed,
 | 
				
			||||||
 | 
						0xa6, 0x49, 0xdb, 0x5d, 0x76, 0xbe, 0xe7, 0x25, 0x3b, 0x3e, 0x0e, 0x5c, 0x94, 0xaa, 0x30, 0xc5,
 | 
				
			||||||
 | 
						0xf3, 0x1b, 0xc5, 0xd7, 0x6b, 0xae, 0xe6, 0x34, 0xe1, 0xc0, 0x8f, 0x97, 0xff, 0x86, 0xd0, 0x8b,
 | 
				
			||||||
 | 
						0x37, 0xb9, 0x40, 0x84, 0x9e, 0xe4, 0x6b, 0xc1, 0x82, 0x28, 0x98, 0x0d, 0x63, 0x5a, 0xe3, 0x43,
 | 
				
			||||||
 | 
						0x18, 0xea, 0xa4, 0x28, 0xc5, 0x57, 0x4b, 0x9c, 0x10, 0xb1, 0x03, 0x30, 0x82, 0x51, 0x52, 0x48,
 | 
				
			||||||
 | 
						0x23, 0xa4, 0x21, 0xfe, 0x94, 0xf8, 0x26, 0x84, 0xf7, 0xa1, 0xbf, 0xe6, 0x26, 0xb9, 0x65, 0x3d,
 | 
				
			||||||
 | 
						0xe2, 0xdc, 0x60, 0xd1, 0x95, 0xb8, 0xc9, 0x24, 0xeb, 0x3b, 0x94, 0x06, 0x8b, 0xfe, 0xb9, 0xcd,
 | 
				
			||||||
 | 
						0x72, 0xc1, 0xce, 0x1c, 0x4a, 0x03, 0x4e, 0xe0, 0x54, 0xc8, 0x94, 0x0d, 0x08, 0xb3, 0x4b, 0x64,
 | 
				
			||||||
 | 
						0x30, 0xc8, 0x64, 0x92, 0x6f, 0x52, 0xc1, 0x42, 0x42, 0xb7, 0x23, 0x3e, 0x85, 0xb0, 0xe4, 0xc6,
 | 
				
			||||||
 | 
						0x08, 0x25, 0x35, 0x1b, 0x46, 0xa7, 0xb3, 0xd1, 0xcb, 0xf1, 0x7c, 0x7b, 0x6a, 0x7b, 0xc4, 0xb8,
 | 
				
			||||||
 | 
						0xa6, 0xf1, 0x35, 0x84, 0x09, 0x2f, 0xcd, 0x46, 0x09, 0xcd, 0x80, 0xa4, 0x0f, 0x5a, 0xd2, 0xf9,
 | 
				
			||||||
 | 
						0x7b, 0xcf, 0x2e, 0xa4, 0x51, 0x55, 0x5c, 0x8b, 0xf1, 0x03, 0x8c, 0x69, 0xbb, 0x5b, 0x9e, 0x8d,
 | 
				
			||||||
 | 
						0xc8, 0x1d, 0xb5, 0xdd, 0xd7, 0x4d, 0x89, 0x8b, 0x68, 0xdb, 0x6c, 0x0e, 0x1d, 0xb0, 0xce, 0xb9,
 | 
				
			||||||
 | 
						0x73, 0x2c, 0xe7, 0x47, 0x53, 0xe2, 0x73, 0x5a, 0x36, 0x7c, 0x07, 0x23, 0x21, 0xd3, 0x3a, 0x65,
 | 
				
			||||||
 | 
						0x4c, 0x29, 0x8f, 0xdb, 0x29, 0x8b, 0x9d, 0xc0, 0x65, 0x34, 0x2d, 0xf8, 0x16, 0x40, 0x89, 0xb2,
 | 
				
			||||||
 | 
						0xd0, 0x99, 0x29, 0x54, 0xc5, 0xee, 0x52, 0xc0, 0xa3, 0x76, 0x40, 0x5c, 0xf3, 0xce, 0xdf, 0x30,
 | 
				
			||||||
 | 
						0x58, 0x7b, 0x26, 0x7f, 0x8a, 0xc4, 0x64, 0x85, 0xd4, 0xec, 0xfc, 0x98, 0xfd, 0x53, 0xcd, 0x7b,
 | 
				
			||||||
 | 
						0xfb, 0xce, 0x80, 0x53, 0x08, 0xd3, 0x4c, 0xf3, 0x55, 0x2e, 0x52, 0x36, 0x89, 0x82, 0x59, 0x18,
 | 
				
			||||||
 | 
						0xd7, 0x33, 0xbe, 0x80, 0x0b, 0x5e, 0x96, 0x79, 0xb5, 0x90, 0xe9, 0x77, 0x77, 0x71, 0x4b, 0xae,
 | 
				
			||||||
 | 
						0x0d, 0xbb, 0x47, 0xb2, 0x63, 0x14, 0x3e, 0x83, 0x89, 0x2f, 0x43, 0x2c, 0xb4, 0x30, 0xd7, 0x5c,
 | 
				
			||||||
 | 
						0x0b, 0x86, 0x24, 0x3f, 0xc0, 0xa7, 0x9f, 0x61, 0xdc, 0xfa, 0x2a, 0xb6, 0x6a, 0xbf, 0x44, 0xe5,
 | 
				
			||||||
 | 
						0xfb, 0x6f, 0x97, 0xf8, 0x04, 0xfa, 0xbf, 0x79, 0xbe, 0x71, 0xd5, 0x3f, 0x68, 0x93, 0xe3, 0xae,
 | 
				
			||||||
 | 
						0x4e, 0xde, 0x04, 0xd3, 0x6f, 0x80, 0x87, 0x57, 0xde, 0x31, 0xf0, 0xf0, 0xee, 0xbb, 0x04, 0x7e,
 | 
				
			||||||
 | 
						0x81, 0xc9, 0x7e, 0x0d, 0xba, 0xc4, 0x2d, 0xe1, 0x7c, 0xaf, 0x14, 0x1d, 0xd3, 0xf6, 0x3a, 0xd2,
 | 
				
			||||||
 | 
						0x21, 0xed, 0xf2, 0x6f, 0x00, 0x83, 0x65, 0xb6, 0x52, 0x5c, 0x55, 0x78, 0x05, 0xa1, 0x97, 0x69,
 | 
				
			||||||
 | 
						0x16, 0xec, 0xbd, 0x0d, 0xaf, 0x99, 0x7f, 0xf4, 0x02, 0xff, 0xd4, 0xb7, 0x7a, 0x5b, 0x90, 0x16,
 | 
				
			||||||
 | 
						0xd5, 0x61, 0x4f, 0xab, 0x33, 0xfa, 0xeb, 0xbe, 0xfa, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x2b, 0x2e,
 | 
				
			||||||
 | 
						0xec, 0x55, 0x8c, 0x05, 0x00, 0x00,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2
									
								
								vendor/CodeMirror
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/CodeMirror
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/CodeMirror updated: dcdf0146e1...97290a687e
									
								
							
							
								
								
									
										9
									
								
								vendor/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/README.md
									
									
									
									
										vendored
									
									
								
							@@ -70,6 +70,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
 | 
				
			|||||||
- **ColdFusion CFC:** [SublimeText/ColdFusion](https://github.com/SublimeText/ColdFusion)
 | 
					- **ColdFusion CFC:** [SublimeText/ColdFusion](https://github.com/SublimeText/ColdFusion)
 | 
				
			||||||
- **COLLADA:** [textmate/xml.tmbundle](https://github.com/textmate/xml.tmbundle)
 | 
					- **COLLADA:** [textmate/xml.tmbundle](https://github.com/textmate/xml.tmbundle)
 | 
				
			||||||
- **Common Lisp:** [textmate/lisp.tmbundle](https://github.com/textmate/lisp.tmbundle)
 | 
					- **Common Lisp:** [textmate/lisp.tmbundle](https://github.com/textmate/lisp.tmbundle)
 | 
				
			||||||
 | 
					- **Common Workflow Language:** [manabuishii/language-cwl](https://github.com/manabuishii/language-cwl)
 | 
				
			||||||
- **Component Pascal:** [textmate/pascal.tmbundle](https://github.com/textmate/pascal.tmbundle)
 | 
					- **Component Pascal:** [textmate/pascal.tmbundle](https://github.com/textmate/pascal.tmbundle)
 | 
				
			||||||
- **Cool:** [anunayk/cool-tmbundle](https://github.com/anunayk/cool-tmbundle)
 | 
					- **Cool:** [anunayk/cool-tmbundle](https://github.com/anunayk/cool-tmbundle)
 | 
				
			||||||
- **Coq:** [mkolosick/Sublime-Coq](https://github.com/mkolosick/Sublime-Coq)
 | 
					- **Coq:** [mkolosick/Sublime-Coq](https://github.com/mkolosick/Sublime-Coq)
 | 
				
			||||||
@@ -101,6 +102,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
 | 
				
			|||||||
- **eC:** [ecere/ec.tmbundle](https://github.com/ecere/ec.tmbundle)
 | 
					- **eC:** [ecere/ec.tmbundle](https://github.com/ecere/ec.tmbundle)
 | 
				
			||||||
- **Ecere Projects:** [textmate/json.tmbundle](https://github.com/textmate/json.tmbundle)
 | 
					- **Ecere Projects:** [textmate/json.tmbundle](https://github.com/textmate/json.tmbundle)
 | 
				
			||||||
- **ECLiPSe:** [alnkpa/sublimeprolog](https://github.com/alnkpa/sublimeprolog)
 | 
					- **ECLiPSe:** [alnkpa/sublimeprolog](https://github.com/alnkpa/sublimeprolog)
 | 
				
			||||||
 | 
					- **Edje Data Collection:** [textmate/json.tmbundle](https://github.com/textmate/json.tmbundle)
 | 
				
			||||||
- **edn:** [atom/language-clojure](https://github.com/atom/language-clojure)
 | 
					- **edn:** [atom/language-clojure](https://github.com/atom/language-clojure)
 | 
				
			||||||
- **Eiffel:** [textmate/eiffel.tmbundle](https://github.com/textmate/eiffel.tmbundle)
 | 
					- **Eiffel:** [textmate/eiffel.tmbundle](https://github.com/textmate/eiffel.tmbundle)
 | 
				
			||||||
- **EJS:** [gregory-m/ejs-tmbundle](https://github.com/gregory-m/ejs-tmbundle)
 | 
					- **EJS:** [gregory-m/ejs-tmbundle](https://github.com/gregory-m/ejs-tmbundle)
 | 
				
			||||||
@@ -167,7 +169,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
 | 
				
			|||||||
- **Ioke:** [vic/ioke-outdated](https://github.com/vic/ioke-outdated)
 | 
					- **Ioke:** [vic/ioke-outdated](https://github.com/vic/ioke-outdated)
 | 
				
			||||||
- **Isabelle:** [lsf37/Isabelle.tmbundle](https://github.com/lsf37/Isabelle.tmbundle)
 | 
					- **Isabelle:** [lsf37/Isabelle.tmbundle](https://github.com/lsf37/Isabelle.tmbundle)
 | 
				
			||||||
- **Isabelle ROOT:** [lsf37/Isabelle.tmbundle](https://github.com/lsf37/Isabelle.tmbundle)
 | 
					- **Isabelle ROOT:** [lsf37/Isabelle.tmbundle](https://github.com/lsf37/Isabelle.tmbundle)
 | 
				
			||||||
- **J:** [bcj/JSyntax](https://github.com/bcj/JSyntax)
 | 
					- **J:** [tikkanz/JSyntax](https://github.com/tikkanz/JSyntax)
 | 
				
			||||||
- **Jasmin:** [atmarksharp/jasmin-sublime](https://github.com/atmarksharp/jasmin-sublime)
 | 
					- **Jasmin:** [atmarksharp/jasmin-sublime](https://github.com/atmarksharp/jasmin-sublime)
 | 
				
			||||||
- **Java:** [textmate/java.tmbundle](https://github.com/textmate/java.tmbundle)
 | 
					- **Java:** [textmate/java.tmbundle](https://github.com/textmate/java.tmbundle)
 | 
				
			||||||
- **Java Server Pages:** [textmate/java.tmbundle](https://github.com/textmate/java.tmbundle)
 | 
					- **Java Server Pages:** [textmate/java.tmbundle](https://github.com/textmate/java.tmbundle)
 | 
				
			||||||
@@ -181,7 +183,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
 | 
				
			|||||||
- **JSONiq:** [wcandillon/language-jsoniq](https://github.com/wcandillon/language-jsoniq)
 | 
					- **JSONiq:** [wcandillon/language-jsoniq](https://github.com/wcandillon/language-jsoniq)
 | 
				
			||||||
- **JSONLD:** [atom/language-javascript](https://github.com/atom/language-javascript)
 | 
					- **JSONLD:** [atom/language-javascript](https://github.com/atom/language-javascript)
 | 
				
			||||||
- **JSX:** [github-linguist/language-babel](https://github.com/github-linguist/language-babel)
 | 
					- **JSX:** [github-linguist/language-babel](https://github.com/github-linguist/language-babel)
 | 
				
			||||||
- **Julia:** [JuliaEditorSupport/Julia.tmbundle](https://github.com/JuliaEditorSupport/Julia.tmbundle)
 | 
					- **Julia:** [JuliaEditorSupport/atom-language-julia](https://github.com/JuliaEditorSupport/atom-language-julia)
 | 
				
			||||||
- **Jupyter Notebook:** [textmate/json.tmbundle](https://github.com/textmate/json.tmbundle)
 | 
					- **Jupyter Notebook:** [textmate/json.tmbundle](https://github.com/textmate/json.tmbundle)
 | 
				
			||||||
- **KiCad Layout:** [Alhadis/language-pcb](https://github.com/Alhadis/language-pcb)
 | 
					- **KiCad Layout:** [Alhadis/language-pcb](https://github.com/Alhadis/language-pcb)
 | 
				
			||||||
- **KiCad Legacy Layout:** [Alhadis/language-pcb](https://github.com/Alhadis/language-pcb)
 | 
					- **KiCad Legacy Layout:** [Alhadis/language-pcb](https://github.com/Alhadis/language-pcb)
 | 
				
			||||||
@@ -276,6 +278,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
 | 
				
			|||||||
- **PLpgSQL:** [textmate/sql.tmbundle](https://github.com/textmate/sql.tmbundle)
 | 
					- **PLpgSQL:** [textmate/sql.tmbundle](https://github.com/textmate/sql.tmbundle)
 | 
				
			||||||
- **PogoScript:** [featurist/PogoScript.tmbundle](https://github.com/featurist/PogoScript.tmbundle)
 | 
					- **PogoScript:** [featurist/PogoScript.tmbundle](https://github.com/featurist/PogoScript.tmbundle)
 | 
				
			||||||
- **Pony:** [CausalityLtd/sublime-pony](https://github.com/CausalityLtd/sublime-pony)
 | 
					- **Pony:** [CausalityLtd/sublime-pony](https://github.com/CausalityLtd/sublime-pony)
 | 
				
			||||||
 | 
					- **PostCSS:** [hudochenkov/Syntax-highlighting-for-PostCSS](https://github.com/hudochenkov/Syntax-highlighting-for-PostCSS)
 | 
				
			||||||
- **PostScript:** [textmate/postscript.tmbundle](https://github.com/textmate/postscript.tmbundle)
 | 
					- **PostScript:** [textmate/postscript.tmbundle](https://github.com/textmate/postscript.tmbundle)
 | 
				
			||||||
- **POV-Ray SDL:** [c-lipka/language-povray](https://github.com/c-lipka/language-povray)
 | 
					- **POV-Ray SDL:** [c-lipka/language-povray](https://github.com/c-lipka/language-povray)
 | 
				
			||||||
- **PowerShell:** [SublimeText/PowerShell](https://github.com/SublimeText/PowerShell)
 | 
					- **PowerShell:** [SublimeText/PowerShell](https://github.com/SublimeText/PowerShell)
 | 
				
			||||||
@@ -348,6 +351,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
 | 
				
			|||||||
- **Stylus:** [billymoon/Stylus](https://github.com/billymoon/Stylus)
 | 
					- **Stylus:** [billymoon/Stylus](https://github.com/billymoon/Stylus)
 | 
				
			||||||
- **Sublime Text Config:** [atom/language-javascript](https://github.com/atom/language-javascript)
 | 
					- **Sublime Text Config:** [atom/language-javascript](https://github.com/atom/language-javascript)
 | 
				
			||||||
- **SubRip Text:** [314eter/atom-language-srt](https://github.com/314eter/atom-language-srt)
 | 
					- **SubRip Text:** [314eter/atom-language-srt](https://github.com/314eter/atom-language-srt)
 | 
				
			||||||
 | 
					- **SugarSS:** [hudochenkov/Syntax-highlighting-for-PostCSS](https://github.com/hudochenkov/Syntax-highlighting-for-PostCSS)
 | 
				
			||||||
- **SuperCollider:** [supercollider/language-supercollider](https://github.com/supercollider/language-supercollider)
 | 
					- **SuperCollider:** [supercollider/language-supercollider](https://github.com/supercollider/language-supercollider)
 | 
				
			||||||
- **SVG:** [textmate/xml.tmbundle](https://github.com/textmate/xml.tmbundle)
 | 
					- **SVG:** [textmate/xml.tmbundle](https://github.com/textmate/xml.tmbundle)
 | 
				
			||||||
- **Swift:** [textmate/swift.tmbundle](https://github.com/textmate/swift.tmbundle)
 | 
					- **Swift:** [textmate/swift.tmbundle](https://github.com/textmate/swift.tmbundle)
 | 
				
			||||||
@@ -404,4 +408,5 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
 | 
				
			|||||||
- **Yacc:** [textmate/bison.tmbundle](https://github.com/textmate/bison.tmbundle)
 | 
					- **Yacc:** [textmate/bison.tmbundle](https://github.com/textmate/bison.tmbundle)
 | 
				
			||||||
- **YAML:** [atom/language-yaml](https://github.com/atom/language-yaml)
 | 
					- **YAML:** [atom/language-yaml](https://github.com/atom/language-yaml)
 | 
				
			||||||
- **YANG:** [DzonyKalafut/language-yang](https://github.com/DzonyKalafut/language-yang)
 | 
					- **YANG:** [DzonyKalafut/language-yang](https://github.com/DzonyKalafut/language-yang)
 | 
				
			||||||
 | 
					- **YARA:** [blacktop/language-yara](https://github.com/blacktop/language-yara)
 | 
				
			||||||
- **Zephir:** [phalcon/zephir-sublime](https://github.com/phalcon/zephir-sublime)
 | 
					- **Zephir:** [phalcon/zephir-sublime](https://github.com/phalcon/zephir-sublime)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/grammars/JSyntax
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/JSyntax
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/JSyntax updated: 74971149b5...4647952123
									
								
							
							
								
								
									
										1
									
								
								vendor/grammars/Julia.tmbundle
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								vendor/grammars/Julia.tmbundle
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/Julia.tmbundle deleted from 443f9e8689
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/Stylus
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/Stylus
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/Stylus updated: 61bab33f37...4b382d28fb
									
								
							
							
								
								
									
										1
									
								
								vendor/grammars/Syntax-highlighting-for-PostCSS
									
									
									
									
										vendored
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								vendor/grammars/Syntax-highlighting-for-PostCSS
									
									
									
									
										vendored
									
									
										Submodule
									
								
							 Submodule vendor/grammars/Syntax-highlighting-for-PostCSS added at 575b918985
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/TypeScript-TmLanguage
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/TypeScript-TmLanguage
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/TypeScript-TmLanguage updated: 824f47ea6e...4b614e2efd
									
								
							
							
								
								
									
										1
									
								
								vendor/grammars/atom-language-julia
									
									
									
									
										vendored
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								vendor/grammars/atom-language-julia
									
									
									
									
										vendored
									
									
										Submodule
									
								
							 Submodule vendor/grammars/atom-language-julia added at 4e8896ed0b
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/atom-language-p4
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/atom-language-p4
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/atom-language-p4 updated: 999e3af389...a349af898d
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/atom-language-perl6
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/atom-language-perl6
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/atom-language-perl6 updated: 611c924d0f...382720261a
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/elixir-tmbundle
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/elixir-tmbundle
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/elixir-tmbundle updated: 641e52c380...f7cd93d6b4
									
								
							
							
								
								
									
										1
									
								
								vendor/grammars/javadoc.tmbundle
									
									
									
									
										vendored
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								vendor/grammars/javadoc.tmbundle
									
									
									
									
										vendored
									
									
										Submodule
									
								
							 Submodule vendor/grammars/javadoc.tmbundle added at 5276d7a93f
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-batchfile
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-batchfile
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-batchfile updated: 6d2b18ef05...163e5ffc8d
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-blade
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-blade
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-blade updated: bae0d6e865...5b2611c46b
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-coffee-script
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-coffee-script
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-coffee-script updated: f822e403c5...b0465e3e80
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-crystal
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-crystal
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-crystal updated: 0e47a5248e...6e966bb589
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-css
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-css
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-css updated: 0f7e61c67d...f4e032d6f3
									
								
							
							
								
								
									
										1
									
								
								vendor/grammars/language-cwl
									
									
									
									
										vendored
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								vendor/grammars/language-cwl
									
									
									
									
										vendored
									
									
										Submodule
									
								
							 Submodule vendor/grammars/language-cwl added at 204ab237d3
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-gfm
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-gfm
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-gfm updated: d7e06213be...76ddd7e2fd
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-javascript
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-javascript
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-javascript updated: 70138ec06a...58cb09d773
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-less
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-less
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-less updated: 733b900b63...c244adad61
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-meson
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-meson
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-meson updated: cf2644ddf4...4846c73f01
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-roff
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-roff
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-roff updated: 3fd0b07a30...0b77518f17
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-ruby
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-ruby
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-ruby updated: 3c78983017...d88a4cfb32
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-shellscript
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-shellscript
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-shellscript updated: 3fcf40105b...152ffbd359
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/language-yaml
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/language-yaml
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/language-yaml updated: 723b6ec9c3...b09319efc8
									
								
							
							
								
								
									
										1
									
								
								vendor/grammars/language-yara
									
									
									
									
										vendored
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								vendor/grammars/language-yara
									
									
									
									
										vendored
									
									
										Submodule
									
								
							 Submodule vendor/grammars/language-yara added at f08eec461a
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/pawn-sublime-language
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/pawn-sublime-language
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/pawn-sublime-language updated: ac815f9c39...8b115b302f
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/sublime-aspectj
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/sublime-aspectj
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/sublime-aspectj updated: 043444fc3f...c1928d2335
									
								
							
							
								
								
									
										2
									
								
								vendor/grammars/sublime-glsl
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								vendor/grammars/sublime-glsl
									
									
									
									
										vendored
									
									
								
							 Submodule vendor/grammars/sublime-glsl updated: 3fc2d90d82...8b47c2f844
									
								
							 Submodule vendor/grammars/wdl-sublime-syntax-highlighter updated: d233794849...403407906d
									
								
							
							
								
								
									
										25
									
								
								vendor/licenses/grammar/Syntax-highlighting-for-PostCSS.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/licenses/grammar/Syntax-highlighting-for-PostCSS.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					type: grammar
 | 
				
			||||||
 | 
					name: Syntax-highlighting-for-PostCSS
 | 
				
			||||||
 | 
					license: mit
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					The MIT License (MIT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright 2017 Aleks Hudochenkov <aleks@hudochenkov.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
				
			||||||
 | 
					this software and associated documentation files (the "Software"), to deal in
 | 
				
			||||||
 | 
					the Software without restriction, including without limitation the rights to
 | 
				
			||||||
 | 
					use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
				
			||||||
 | 
					the Software, and to permit persons to whom the Software is furnished to do so,
 | 
				
			||||||
 | 
					subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
				
			||||||
 | 
					FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
				
			||||||
 | 
					COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
				
			||||||
 | 
					IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
				
			||||||
 | 
					CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
							
								
								
									
										27
									
								
								vendor/licenses/grammar/atom-language-julia.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/licenses/grammar/atom-language-julia.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					type: grammar
 | 
				
			||||||
 | 
					name: atom-language-julia
 | 
				
			||||||
 | 
					license: mit
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					The atom-language-julia package is licensed under the MIT "Expat" License:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> Copyright (c) 2015
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					> Permission is hereby granted, free of charge, to any person obtaining
 | 
				
			||||||
 | 
					> a copy of this software and associated documentation files (the
 | 
				
			||||||
 | 
					> "Software"), to deal in the Software without restriction, including
 | 
				
			||||||
 | 
					> without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					> distribute, sublicense, and/or sell copies of the Software, and to
 | 
				
			||||||
 | 
					> permit persons to whom the Software is furnished to do so, subject to
 | 
				
			||||||
 | 
					> the following conditions:
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					> The above copyright notice and this permission notice shall be
 | 
				
			||||||
 | 
					> included in all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
				
			||||||
 | 
					> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
@@ -1,10 +1,9 @@
 | 
				
			|||||||
---
 | 
					---
 | 
				
			||||||
type: grammar
 | 
					type: grammar
 | 
				
			||||||
name: ruby.tmbundle
 | 
					name: javadoc.tmbundle
 | 
				
			||||||
license: permissive
 | 
					license: permissive
 | 
				
			||||||
curated: true
 | 
					curated: true
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					 | 
				
			||||||
If not otherwise specified (see below), files in this repository fall under the following license:
 | 
					If not otherwise specified (see below), files in this repository fall under the following license:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Permission to copy, use, modify, sell and distribute this
 | 
						Permission to copy, use, modify, sell and distribute this
 | 
				
			||||||
@@ -1,19 +1,18 @@
 | 
				
			|||||||
---
 | 
					---
 | 
				
			||||||
type: grammar
 | 
					type: grammar
 | 
				
			||||||
name: Julia.tmbundle
 | 
					name: language-cwl
 | 
				
			||||||
license: mit
 | 
					license: mit
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
Copyright (c) 2012-2014 Stefan Karpinski, Elliot Saba, Dirk Gadsden,
 | 
					MIT License
 | 
				
			||||||
Adam Strzelecki, Jonathan Malmaud and other contributors:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
https://github.com/JuliaEditorSupport/Julia.tmbundle/contributors
 | 
					Copyright (c) 2017 Manabu Ishii RIKEN Bioinformatics Research Unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
this software and associated documentation files (the "Software"), to deal in
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
the Software without restriction, including without limitation the rights to
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
of the Software, and to permit persons to whom the Software is furnished to do
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
so, subject to the following conditions:
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The above copyright notice and this permission notice shall be included in all
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
copies or substantial portions of the Software.
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
							
								
								
									
										26
									
								
								vendor/licenses/grammar/language-yara.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/licenses/grammar/language-yara.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					type: grammar
 | 
				
			||||||
 | 
					name: language-yara
 | 
				
			||||||
 | 
					license: mit
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					The MIT License (MIT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2014-2016 Blacktop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					SOFTWARE.
 | 
				
			||||||
		Reference in New Issue
	
	Block a user