Compare commits

..

199 Commits

Author SHA1 Message Date
Arfon Smith
c8b30a62f9 Merge pull request #2741 from github/cut-release-v4.7.2
Cut release v4.7.2
2015-11-23 15:24:29 -06:00
Arfon Smith
48dfdd2dfe Bumping version to v4.7.2 2015-11-23 14:04:48 -06:00
Arfon Smith
68727f724a Grammars update 2015-11-23 13:53:53 -06:00
Arfon Smith
49f3eb1286 Merge pull request #2736 from ppwwyyxx/patch-1
add jquery.fancybox.css to vendor list
2015-11-22 21:16:45 -06:00
Yuxin Wu
8ab94a8643 Use one line for jquery fancybox in vendor
(just another commit to pass CLA check
2015-11-21 21:55:08 -05:00
Yuxin Wu
f72c337c5b add jquery.fancybox.css to vendor list
fancybox has both js and css
2015-11-21 21:48:03 -05:00
Arfon Smith
d22321de07 Merge pull request #2733 from github/cake
.cake
2015-11-19 20:34:36 -06:00
Arfon Smith
473e5db51f Adding sample for Coffeescript too 2015-11-19 20:24:23 -06:00
Arfon Smith
8b9fc4683a Merge branch 'master' into cake 2015-11-19 20:19:08 -06:00
Arfon Smith
3b4415cc3c Merge pull request #2729 from larsbrinkhoff/fortran
Recognise END statement in FORTRAN files.
2015-11-19 20:07:10 -06:00
Arfon Smith
2afce1754a Merge pull request #2731 from soc/patch-1
Change Scala language color to Scala language's main color
2015-11-19 20:06:22 -06:00
Arfon Smith
f232b93214 Merge pull request #2728 from larsbrinkhoff/fs
Add new .eam.fs sample for Formatted.
2015-11-19 20:05:45 -06:00
soc
db64f192fa Change Scala language color to Scala language's main color 2015-11-19 15:25:55 +01:00
Lars Brinkhoff
ca96ecdc55 Recognise END statement in FORTRAN files. 2015-11-19 08:51:13 +01:00
Lars Brinkhoff
2a06d1aa19 Add new sample for Formatted.
Sample from qingguang/lammps-sph; GPL v2 license.
2015-11-19 07:59:31 +01:00
Arfon Smith
b2fa2a1f46 Merge pull request #2655 from iblech/pickle
Detect Pickle data dumps (.p, .pkl, .pickle)
2015-11-16 17:57:53 -06:00
Ingo Blechschmidt
6839516b5c Only classify .pkl files as Pickle data dumps
It seems to be the dominant extension at the moment, even though several
Python resources use `.p` or `.pickle`. This was discussed in #2655.
2015-11-17 00:05:22 +01:00
Arfon Smith
7247c80fac Merge pull request #2722 from github/cut-release-v4.7.1
Cut release v4.7.1
2015-11-12 19:51:41 -06:00
Arfon Smith
01d05d1d4e Bumping to v4.7.1 2015-11-12 18:43:16 -06:00
Arfon Smith
8db4cc482e Grammar update 2015-11-12 18:42:24 -06:00
Arfon Smith
074f17ed98 Merge pull request #2712 from matiasinsaurralde/master
Support for JSCAD files
2015-11-12 18:18:52 -06:00
Arfon Smith
68b553ea55 Updating grammars 2015-11-10 09:57:04 +00:00
Arfon Smith
fd5da9cb15 Merge pull request #2690 from github/licensee-6
Upgrade to licensee 6
2015-11-10 09:41:09 +00:00
Arfon Smith
d081f687b0 Merge branch 'master' into licensee-6 2015-11-10 09:34:39 +00:00
Arfon Smith
34abe5b983 Merge pull request #2717 from meatballhat/supercollider-grammar
Add SuperCollider grammar
2015-11-10 09:31:24 +00:00
Arfon Smith
5765f1faf1 Merge pull request #2718 from meatballhat/travis-apt-update
Fetch libicu via Travis, switch back to container-based
2015-11-10 09:30:04 +00:00
Dan Buch
550b67215c Fetch libicu via Travis, switch back to container-based
This is a test.  I don't understand the details of how the `bundle config
build.charlock_holmes` bit works/fails, so the intent here is to get a PR posted
for purposes of getting feedback via the full Travis machinery.
2015-11-08 06:41:22 -05:00
Dan Buch
d7b2826113 Add SuperCollider grammar
plus a few minor language support updates including:

- recognize `sclang` and `scsynth` interpreters
- set `tm_scope: source.supercollider`
- reorder extensions so that `.sc` is primary
2015-11-08 06:28:14 -05:00
Arfon Smith
b4f94c7c25 Merge pull request #2706 from redroot/add-csl-as-xml-support
adding csl as an extension for XML, included sample
2015-11-05 09:07:49 -08:00
Arfon Smith
d24677adbb Merge pull request #2716 from github/faster-string-tokenizer
Use negative lookbehind when tokenizing string literals
2015-11-05 08:40:34 -08:00
Arfon Smith
04f981eeac Merge pull request #2714 from github/aroben-patch-1
Remove mentions of treatment of vendored files in diffs
2015-11-05 08:14:26 -08:00
Arfon Smith
b53d84d8ff Merge pull request #2600 from manveru/pony-language
Add Pony language
2015-11-05 08:08:38 -08:00
Adam Roben
fea8bb21a0 Use negative lookbehind when tokenizing string literals
This can double the speed of tokenizing large RTF files that use \'hh
escape sequences.
2015-11-05 10:18:44 -05:00
Adam Roben
996ed8a8b1 Remove mentions of treatment of vendored files in diffs
Vendored files are treated just like any other files when diffing on github.com.
2015-11-04 13:26:24 -05:00
Matias Insaurralde
daef164163 adding jscad sample file 2015-11-03 00:24:15 -03:00
Matias Insaurralde
61a5cab1f2 adding extension for OpenJSCAD 2015-11-03 00:03:00 -03:00
Redth
2fddaaf3d7 Reordered extensions so the primary .cs is first 2015-10-31 12:45:54 -04:00
Redth
741d246581 Add .cake extension for C#
This adds the .cake file extension to the C# language.

Here is a search in the wild: https://github.com/search?q=extension%3Acake+NOT+coffee&type=Code

Cake (C# Make) is a cross platform build automation system with a C# DSL to do things like compiling code, copy files/folders, running unit tests, compress files and build NuGet packages.

You can find out out more about cake here: http://cakebuild.net/
2015-10-30 15:06:38 -04:00
redroot
1b23e81541 adding csl as an extension for XML, included sample 2015-10-30 10:40:15 +00:00
Arfon Smith
362d300cb0 Blob not FileBlob 2015-10-26 09:06:42 +00:00
Arfon Smith
932726863f Merge branch 'master' into licensee-6 2015-10-23 10:29:47 +01:00
Arfon Smith
a35a3e98ce Merge pull request #2702 from github/drop-ruby-1.9.3
Dropping support for Ruby 1.9.3
2015-10-23 10:29:13 +01:00
Arfon Smith
7c404e72d2 Dropping support for Ruby 1.9.3 2015-10-23 10:20:31 +01:00
Arfon Smith
8736e2305d Merge pull request #2700 from pchaigno/django-alias
Django as an alias for HTML+Django
2015-10-22 20:39:14 +01:00
Paul Chaignon
a13664698f Django as an alias for HTML+Django 2015-10-22 20:28:40 +02:00
Arfon Smith
6e934067a8 Merge pull request #2698 from phase/master
Change D color to match the website
2015-10-22 09:26:31 +01:00
phase
3040642f97 Change D color to its logo 2015-10-21 16:42:43 -07:00
phase
dd7e44f957 Change D color to match the website
The original yellow color doesn't fit D very well, and it looks an awful lot like the color for JavaScript. This changes it to the color used on the website's sidebar, and nice dark maroon: http://www.colorpicker.com/2e2324
2015-10-21 15:34:25 -07:00
Arfon Smith
6b56a243e7 Merge pull request #2696 from github/cut-linguist-4.7.0
Bumping to version 4.7.0
2015-10-21 10:19:16 +01:00
Arfon Smith
5d08605aef Bumping to version 4.7.0 2015-10-21 09:04:17 +01:00
Arfon Smith
bf705cbaf2 Grammars update 2015-10-21 09:02:56 +01:00
Arfon Smith
fe827896e0 Merge pull request #2681 from miek/kicad-brd-extension
Add .brd extension for KiCad
2015-10-21 08:55:05 +01:00
Arfon Smith
317219e479 Merge branch 'master' into licensee-6 2015-10-21 08:51:10 +01:00
Arfon Smith
64e7df7596 Merge pull request #2694 from github/memory_blob
Memory blob
2015-10-21 08:49:42 +01:00
Arfon Smith
b3ff84872b Merge branch 'master' into memory_blob 2015-10-20 19:24:43 +01:00
Arfon Smith
5d176a781c Fixing the build :-\ 2015-10-20 19:24:04 +01:00
Arfon Smith
e0c97f97ba Merge branch 'master' into memory_blob 2015-10-20 12:36:26 +01:00
Arfon Smith
83f358976e Fixing up some old MemoryBlob references 2015-10-20 12:33:43 +01:00
Arfon Smith
9ee6153891 Merge pull request #2676 from lucky/master
Support for files generated by Racc.
2015-10-19 12:05:12 +01:00
Arfon Smith
825e640061 Merge pull request #2684 from jeffkreeftmeijer/eex
Add EEx (Embedded Elixir)
2015-10-19 12:02:18 +01:00
Arfon Smith
e5ae213839 Merge pull request #2689 from edendramis/master
Add FreeMarker syntax highlighting
2015-10-19 12:00:38 +01:00
Arfon Smith
74e034c689 Merge pull request #2686 from pchaigno/metal
Support for Metal language
2015-10-19 11:49:36 +01:00
Evangelia Dendramis
a55a60a161 removing group and search term 2015-10-16 18:19:53 -07:00
Brandon Keepers
9d865ec018 license of factor grammar is now detected properly 2015-10-16 15:16:04 -04:00
Brandon Keepers
8b01e3dead Upgrade to licensee 6.0.0b1 2015-10-16 15:15:34 -04:00
edendramis
9e3cc01715 adding FreeMarker to grammars.yml 2015-10-16 09:54:17 -07:00
edendramis
0f204767a9 updating examples 2015-10-15 14:48:20 -07:00
edendramis
11e3251efd adding samples 2015-10-15 14:43:02 -07:00
edendramis
1f1416a5f7 adding freemarker grammar 2015-10-15 14:15:27 -07:00
edendramis
b3786f3825 Merge remote-tracking branch 'upstream/master' 2015-10-15 14:07:13 -07:00
Paul Chaignon
09c2eee91e Support for Metal language 2015-10-13 07:57:58 +02:00
Arfon Smith
dc78b14902 Merge pull request #2683 from hipikat/patch-1
Correct typo ("Any information you [c]an add")
2015-10-12 10:09:17 +01:00
Arfon Smith
500ce0959a Merge branch 'master' into memory_blob 2015-10-12 09:49:22 +01:00
Adam Wright
aa0c9e3572 Correct typo ("Any information you [c]an add") 2015-10-12 14:40:18 +08:00
Mike Walters
e6de75d48a Add .brd extension for KiCad 2015-10-11 23:50:29 +01:00
Arfon Smith
a5ad0a34f8 Merge pull request #2675 from fbonzon/master
Add .phps extension for PHP
2015-10-11 21:32:17 +01:00
Arfon Smith
6e609cc4e3 Merge pull request #2680 from k2b6s9j/patch-1
The Crystal Grammar repository has moved.
2015-10-11 21:31:55 +01:00
Kepler Sticka-Jones
27727a927f The Crystal Grammar repository has moved.
And I'm kinda thinking about changing my GitHub name...
2015-10-10 23:49:07 -06:00
Jared Kuolt
5ff580df0a Support for files generated by Racc.
This changeset includes a sample racc file from [this auto-generated
file](44e9bf0440/lib/rjson/parser.rb)
(MIT-licensed).

[Racc](https://github.com/tenderlove/racc) Racc is an LALR(1) parser
generator. It is written in Ruby itself, and generates ruby programs.
2015-10-09 16:20:59 -07:00
Jeff Kreeftmeijer
b34acac722 Add EEx (Embedded Elixir)
EEx is embedded Elixir: http://elixir-lang.org/docs/v1.0/eex/. Here's
some in-the-wild usage on Github: https://github.com/search?p=100&q=extension%3Aeex+NOT+nothack&ref=searchresults&type=Code&utf8=✓

This uses the "html_elixir" Ace mode, which was added in this pull
request on the Ace project: https://github.com/ajaxorg/ace/pull/2696
2015-10-10 00:20:38 +02:00
François B
37840856ed Add .phps extension for PHP
.phps stands for "PHP Source"

Useful to show examples of PHP code. A properly-configured server will
output a .phps file as is, with color-formated source code instead of
the HTML that would normally be generated.

Usage in GitHub:
https://github.com/search?utf8=%E2%9C%93&q=extension%3Aphps+NOT+nothack&
type=Code

Example taken from:
https://github.com/PHPMailer/PHPMailer/blob/master/examples/mail.phps
2015-10-09 14:43:22 +02:00
Brandon Keepers
acfad4371f Mention alphabetical order in contributing docs
Closes #2649
2015-10-07 19:41:37 -04:00
Arfon Smith
ae42cc0307 Merge pull request #2672 from github/cut-release-v4.6.4
Cut release v4.6.4
2015-10-05 11:15:35 +01:00
Arfon Smith
d06860df37 Bumping version to v4.6.4 2015-10-05 09:45:32 +01:00
Arfon Smith
7d5d162f6b Updating FSharp grammars to match 2015-10-05 09:45:05 +01:00
Arfon Smith
d39a75b68b Grammar updates 2015-10-05 09:41:56 +01:00
Arfon Smith
d72f7311f6 Merge pull request #2648 from jaredpetersen/master
Added .pck PLSQL file extension
2015-10-05 09:23:56 +01:00
Arfon Smith
3f81b7c179 Merge pull request #2640 from wizawu/master
Add new extension .tsx for TypeScript
2015-10-05 09:21:46 +01:00
Arfon Smith
33d1255a5a Merge pull request #2671 from pchaigno/change-stata-grammar-repo
Change Stata grammar repo
2015-10-05 09:15:15 +01:00
Paul Chaignon
0ebea6a0ff Use pschumm/Stata.tmbundle 2015-10-04 20:45:33 +02:00
Paul Chaignon
c28da3a4a9 Remove statatmbundle/Stata.tmbundle grammar 2015-10-04 20:42:29 +02:00
wizawu
d6d368a65d Replace the sample file for .tsx extension
The sample file is from https://github.com/Microsoft/TypeScript/blob/master/tests/cases/conformance/jsx/tsxAttributeResolution9.tsx
2015-10-03 11:01:22 +08:00
wizawu
c5be9cc3e9 Add .tsx extension for XML
The sample file is from https://github.com/nyxcharon/tiled/blob/master/src/examples/water.tsx
2015-10-02 19:50:10 +08:00
E
c462c2bd31 add FreeMarker to languages.yml 2015-10-01 13:59:52 -07:00
wizawu
3426165621 Add a TypeScript sample with .tsx extension 2015-09-30 13:45:38 +08:00
Vicent Marti
98b99e38bb Merge pull request #2654 from github/vmg/git-linguist-fixes
Small fixes for git-linguist
2015-09-28 11:12:49 +02:00
Vicent Marti
d8e3bec499 Bump version 2015-09-28 01:45:49 -07:00
Vicent Marti
7c759d4d29 git-linguist: Do not write cache if repo is gone 2015-09-28 01:45:49 -07:00
Vicent Marti
41d438b47e repository: Do not attempt to scan large repos 2015-09-28 01:45:49 -07:00
Vicent Marti
41911d6921 git-linguist: Properly handle $GIT_DIR from git 2015-09-28 01:45:49 -07:00
Arfon Smith
dca18d77cb Merge pull request #2656 from iblech/better-test-description
Clarified that only nonprimary extensions should be sorted
2015-09-27 20:34:30 +01:00
Ingo Blechschmidt
040af5dad2 Clarify that only nonprimary extensions should be sorted 2015-09-25 19:23:06 +02:00
Ingo Blechschmidt
01bb6c37ab Detect Pickle data dumps (.p, .pkl, .pickle) 2015-09-25 19:06:50 +02:00
Jared Petersen
c624d68628 Added .pck PLSQL file extension 2015-09-24 07:59:06 -07:00
Arfon Smith
4867c49bd9 Merge pull request #2642 from github/license-in-gemspec
Include LICENSE in gem
2015-09-23 09:19:18 +01:00
Brandon Keepers
a354eddf4b Update github-linguist.gemspec 2015-09-22 16:33:08 -04:00
Vicent Marti
9b78c533a5 Merge pull request #2641 from github/js-syntax-fix
github-linguist-grammars 4.6.2
2015-09-21 21:56:33 +02:00
Mislav Marohnić
090ea576b9 github-linguist-grammars 4.6.2 2015-09-21 21:23:40 +02:00
Mislav Marohnić
6a2d33a4b3 Bump language-javascript for syntax highlighting fix
This is primarily to pull
https://github.com/atom/language-javascript/pull/227

Full changelog:
c5c381e...7b14bbb (diff-46d5c1ca71eaebb92619d6c7abc9388d)
2015-09-21 19:04:30 +02:00
wizawu
b54a9c7412 Add new extension .tsx for TypeScript
TypeScript 1.6 has introduced a new .tsx file extension.
2015-09-21 13:48:30 +08:00
Vicent Marti
2c62da7834 Merge pull request #2636 from github/vmg/git-linguist-oid
git-linguist: Delay loading @commit_oid
2015-09-16 16:48:12 +02:00
Vicent Marti
0145a0adb2 git-linguist: Delay loading @commit_oid 2015-09-16 05:50:35 -07:00
Vicent Marti
473282d64c Merge pull request #2630 from github/vmg/memory
4.6.0: Reduce memory pressure
2015-09-15 11:19:45 +02:00
Vicent Marti
c2c068e9db Bump version to 4.6.0 2015-09-14 08:43:10 -07:00
Vicent Marti
13d1f662d1 Add the git-linguist helper 2015-09-14 08:42:51 -07:00
Arfon Smith
bdd57f58a0 Merge pull request #2625 from github/handlebars-group
Adding Handlebars to the HTML group
2015-09-09 09:18:11 +01:00
Arfon Smith
b1bcabd6e6 Adding Handlebars to the HTML group 2015-09-08 12:25:05 +01:00
Arfon Smith
e128c3fa82 Merge pull request #2622 from miksen/patch-1
Language bar clarification in README.md
2015-09-08 12:08:42 +01:00
Arfon Smith
efac9fe750 Merge pull request #2624 from pchaigno/jsx-grammar
New JSX language under JavaScript group
2015-09-08 11:01:44 +01:00
Arfon Smith
2b8545a8fa Merge pull request #2567 from pcantrell/objc-import-statement
#import "*.h" detection for Objective-C
2015-09-08 10:53:32 +01:00
Vicent Marti
b275b5d728 Soften memory pressure 2015-09-07 22:03:29 +02:00
Paul Chaignon
1f46cfafa7 New JSX language under JavaScript group
A specific grammar is needed to highlight .jsx files
Thus, there are now in a distinct language but still in the JavaScript group
2015-09-05 13:31:17 +02:00
miksen
b1dcdf3418 Language bar clarification in README.md
Clarified what the percentages in the Language bar are based on.
2015-09-04 11:49:10 +02:00
Paul Cantrell
4bfd65deb8 #import "*.h" detection for Objective-C 2015-09-03 22:10:27 -05:00
Paul Chaignon
213cf322f5 Merge branch 'master' into blob_in_memory 2015-09-04 00:55:39 +02:00
Arfon Smith
61102812a0 Merge pull request #2619 from github/linguist-generated
Adding support for generated overrides
2015-09-03 15:02:16 +01:00
Arfon Smith
580cfce7fb Adding support for generated overrides 2015-09-03 14:39:27 +01:00
Arfon Smith
f1383d7a45 Merge pull request #2616 from scttnlsn/patch-1
Ignore spec fixtures
2015-09-02 18:35:07 +01:00
Scott Nelson
e4ce5bfe39 Ignore spec fixtures 2015-09-02 12:52:25 -04:00
Arfon Smith
6ed64f25a2 Merge pull request #2607 from Alhadis/master
Add .geojson/.topojson as JSON extensions / Fix NCL colour
2015-09-02 10:13:31 +01:00
Alhadis
114a331106 Add ".topojson" as a JSON extension 2015-09-02 07:04:51 +10:00
Arfon Smith
9aa24a216a Merge pull request #2612 from github/cut-release-v4.5.15
Cut release v4.5.15
2015-09-01 21:04:40 +01:00
Arfon Smith
13702451ab Bumping to v4.5.15 2015-09-01 19:13:02 +01:00
Arfon Smith
f0242f6f97 Updating grammars 2015-09-01 19:12:27 +01:00
Arfon Smith
9775820398 Merge pull request #2591 from jtbandes/master
Vendored definitions for Xcode-related files
2015-09-01 18:53:08 +01:00
Arfon Smith
7daf26bcd0 Merge pull request #2604 from larsbrinkhoff/alphabetise-heuristics
Alphabetise heuristics.
2015-09-01 15:25:49 +01:00
Arfon Smith
231f705098 Merge pull request #2606 from thejameskyle/jsproj
Add .jsproj extension
2015-09-01 15:23:53 +01:00
Arfon Smith
893ab8fd8d Merge pull request #2610 from ismail-arilik/patch-1
Add color for the PL/SQL language.
2015-09-01 15:20:49 +01:00
ismail-arilik
5afdd2c533 Add color for the PL/SQL language.
I have added color to the PL/SQL language: #dad8d8. I take this color from a window background which evokes the interface of the language.
2015-09-01 14:23:59 +03:00
Lars Brinkhoff
e4f5c0066a Add checks to keep heuristics alphabetised. 2015-09-01 08:21:34 +02:00
Alhadis
a167f852dd Alphabetise JSON extensions 2015-09-01 07:33:07 +10:00
Alhadis
b428bce126 Quote NCL language's colour value
Without double-quotes, the hex colour is interpreted as a YAML comment.

Originally added in 2d39258.
2015-09-01 07:24:17 +10:00
Alhadis
e62d0e19a5 Add ".geojson" as a JSON extension 2015-09-01 07:12:18 +10:00
James Kyle
9b8bf9068f Move jsproj example to xml directory 2015-08-31 11:35:01 -07:00
James Kyle
6e05edc350 Add .jsproj extension 2015-08-31 10:26:29 -07:00
Lars Brinkhoff
dd8eaf2893 Alphabetise heuristics. 2015-08-31 08:53:51 +02:00
Michael Fellinger
ecc750f445 Merge branch 'master' of https://github.com/github/linguist into origin/patch-1
* 'master' of https://github.com/github/linguist:
  Switch to Apache License.
  also add help for unapproved licenses
  Update X10 grammar license.
  add some help text to license test
  Fix typo in Obj-C heuristic keyword
  Add the X10 language (http://x10-lang.org/).
  Sublime Text workspace files as vendored
  Make Slick regexp more general
  Tests for new vendored files
  Test for new CodeMirror regexp
  New JS vendored files
  Fix CodeMirror regex for vendored files
  added *.lslp to samples/LSL folder
  added *.lslp as LSL(Linden Scripting Language)

Conflicts:
	.gitmodules
2015-08-28 14:08:31 -04:00
Michael Fellinger
cf5268a7d4 add Pony language 2015-08-28 14:04:10 -04:00
Ben Balter
e24efad5ff Merge pull request #2594 from github/license-help
Add some additional help text to license test
2015-08-26 14:55:37 -04:00
Arfon Smith
58a34cdb7d Merge pull request #2589 from mandel/master
Add the X10 language.
2015-08-26 19:36:54 +01:00
Louis Mandel
b1c6b330e9 Switch to Apache License. 2015-08-26 14:26:30 -04:00
Ben Balter
7c3e265033 also add help for unapproved licenses 2015-08-26 12:31:29 -04:00
Louis Mandel
13695a716c Update X10 grammar license. 2015-08-26 09:46:02 -04:00
Ben Balter
c9e43804d6 add some help text to license test 2015-08-26 09:26:04 -04:00
Arfon Smith
1535e3553e Merge pull request #2580 from LeonaMorro/master
add *.lslp as an additional extension for LSL (LindenScriptingLanguage)
2015-08-26 14:09:48 +01:00
Arfon Smith
0ac05bbbeb Merge pull request #2582 from pchaigno/vendor-libraries
Vendored JS files
2015-08-26 14:02:57 +01:00
Arfon Smith
d3f979d640 Merge pull request #2592 from jtbandes/typo
Fix typo in Obj-C heuristic keyword
2015-08-26 12:52:05 +01:00
Jacob Bandes-Storch
0e9ded45dc Fix typo in Obj-C heuristic keyword
`synchronised` → `synchronized`
2015-08-26 00:34:00 -07:00
Jacob Bandes-Storch
a2ca886510 Vendored definitions for Xcode-related files 2015-08-25 23:42:20 -07:00
Louis Mandel
25a1af3775 Add the X10 language (http://x10-lang.org/). 2015-08-24 13:26:43 -04:00
Paul Chaignon
0d8e0a2970 Sublime Text workspace files as vendored 2015-08-24 12:32:26 +02:00
Paul Chaignon
c0fff6c8a8 Make Slick regexp more general 2015-08-21 12:30:01 +02:00
Paul Chaignon
e6b4428614 Tests for new vendored files 2015-08-21 12:24:04 +02:00
Paul Chaignon
4e6e69833d Test for new CodeMirror regexp 2015-08-21 12:15:17 +02:00
Paul Chaignon
1d9faff4c6 New JS vendored files 2015-08-21 12:13:42 +02:00
Paul Chaignon
7025cbe760 Fix CodeMirror regex for vendored files 2015-08-21 12:12:52 +02:00
LeonaMorro
e922b7c2ca added *.lslp to samples/LSL folder 2015-08-21 11:44:23 +02:00
LeonaMorro
96518d2d0f added *.lslp as LSL(Linden Scripting Language) 2015-08-21 11:17:12 +02:00
Arfon Smith
1241b20ba1 Merge pull request #2578 from blakeembrey/correct-raml-type
Make RAML a markup language
2015-08-20 20:56:21 +01:00
Ben Balter
f03f5c1628 Merge pull request #2568 from github/licensee
Use Licensee to classify submodule licenses
2015-08-20 15:42:50 -04:00
Ben Balter
cb550a3662 remove some random submodules 2015-08-20 15:30:51 -04:00
Ben Balter
d1f90d61c5 Merge branch 'master' into licensee 2015-08-20 15:25:15 -04:00
Blake Embrey
16e65fe189 Make RAML a markup language
RAML was originally merged as a data language, but this seems like an incorrect definition. I changed it to be markup instead, which will also result in RAML appearing in repo statistics.
2015-08-20 10:07:44 -07:00
Ben Balter
62a0faa729 let us 2015-08-20 12:23:52 -04:00
Ben Balter
fbb3ab2292 batch license test output 2015-08-20 11:38:31 -04:00
Arfon Smith
b3b75e5ef8 Merge pull request #2574 from github/perl-t
Adding Perl/Perl6 heuristic for '.t'
2015-08-20 10:29:52 +01:00
Arfon Smith
8b36210db5 Merge pull request #2573 from a0viedo/patch-1
relativize link in readme
2015-08-20 10:25:02 +01:00
Arfon Smith
a74f3b3e46 Adding Perl/Perl6 heuristic for '.t' 2015-08-20 10:16:52 +01:00
Alejandro Oviedo
e214a52de5 relativize link in readme
...so it could link properly in other branches and forks.
2015-08-19 19:15:05 -03:00
Arfon Smith
0624a9395c Merge pull request #2571 from pchaigno/prolog-grammar
New grammars for Prolog and ECLiPSe
2015-08-19 21:44:13 +01:00
Arfon Smith
b2e7f7ffa6 Merge pull request #2570 from pchaigno/typescript-grammar
New grammar for Typescript
2015-08-19 21:41:15 +01:00
Arfon Smith
b312b39a10 Merge pull request #2572 from pchaigno/rmarkdown-tmscope
TextMate scope for RMarkdown
2015-08-19 21:38:42 +01:00
Paul Chaignon
80e2d112b2 tm_scope for RMarkdown 2015-08-19 22:07:23 +02:00
Paul Chaignon
519b169df0 New grammar for Typescript from Sublime Text package 2015-08-19 21:30:24 +02:00
Paul Chaignon
5c2cfbc334 Remove Typescript grammar 2015-08-19 21:27:40 +02:00
Paul Chaignon
7d91e4959a Dissociate ECLiPSe from Prolog
ECLiPSe syntax is slightly different from Prolog syntax
ECLiPSe is in the Prolog group so it will only be highlighted differently
2015-08-19 20:56:14 +02:00
Paul Chaignon
0c5aa2a7eb Merge branch 'master' into prolog-grammar 2015-08-19 20:46:15 +02:00
Paul Chaignon
0d7a264981 Update submodule for Prolog grammar 2015-08-19 20:43:16 +02:00
Arfon Smith
52ff2d2e74 Merge pull request #2557 from pchaigno/mozilla-public-license
Recognize the Mozilla Public License for grammars
2015-08-19 19:21:33 +01:00
Ben Balter
8a7ceaa845 bump licensee to support ruby 1.9.3 2015-08-19 13:22:31 -04:00
Ben Balter
fd9ce2d1cf use licensee to classify submodule licenses 2015-08-19 12:54:21 -04:00
Paul Chaignon
2c2b37bec3 Reorganize tests
Rename test_memory_blob.rb to test_blob.rb for consistence with last commit
2015-08-19 18:07:42 +02:00
Paul Chaignon
c777f2d388 Merge branch 'master' into blob_in_memory 2015-08-19 18:02:31 +02:00
Paul Chaignon
eca10056a8 Rename MemoryBlob to Blob 2015-08-19 17:29:35 +02:00
Paul Chaignon
6226a46988 Recognize the Mozilla Public License for grammars 2015-08-13 17:35:01 +02:00
Paul Chaignon
8d216f0c43 Grammar for Prolog from Sublime Text package
MPLv2 License is currently unrecognized
2015-08-13 17:15:04 +02:00
Paul Chaignon
7f5bb25542 Remove grammar for Prolog from TextMate bundle 2015-08-13 16:56:21 +02:00
Paul Chaignon
5a646384f6 FileBlob extends MemoryBlob 2015-07-12 20:56:51 +02:00
Paul Chaignon
8917f1a91a MemoryBlob class: wrapper around the content of a file
Makes it possible to detect the language of a snippet of code
without having an actual file on disk
Will allow github-markup to use Linguist without restricting its API
2015-07-12 20:28:42 +02:00
144 changed files with 24123 additions and 984 deletions

35
.gitmodules vendored
View File

@@ -85,6 +85,9 @@
[submodule "vendor/grammars/language-shellscript"]
path = vendor/grammars/language-shellscript
url = https://github.com/atom/language-shellscript
[submodule "vendor/grammars/language-supercollider"]
path = vendor/grammars/language-supercollider
url = https://github.com/supercollider/language-supercollider
[submodule "vendor/grammars/language-yaml"]
path = vendor/grammars/language-yaml
url = https://github.com/atom/language-yaml
@@ -169,9 +172,6 @@
[submodule "vendor/grammars/sublime-idris"]
path = vendor/grammars/sublime-idris
url = https://github.com/laughedelic/sublime-idris
[submodule "vendor/grammars/sublime-better-typescript"]
path = vendor/grammars/sublime-better-typescript
url = https://github.com/lavrton/sublime-better-typescript
[submodule "vendor/grammars/moonscript-tmbundle"]
path = vendor/grammars/moonscript-tmbundle
url = https://github.com/leafo/moonscript-tmbundle
@@ -256,9 +256,6 @@
[submodule "vendor/grammars/SublimeXtend"]
path = vendor/grammars/SublimeXtend
url = https://github.com/staltz/SublimeXtend
[submodule "vendor/grammars/Stata.tmbundle"]
path = vendor/grammars/Stata.tmbundle
url = https://github.com/statatmbundle/Stata.tmbundle
[submodule "vendor/grammars/Vala-TMBundle"]
path = vendor/grammars/Vala-TMBundle
url = https://github.com/technosophos/Vala-TMBundle
@@ -397,9 +394,6 @@
[submodule "vendor/grammars/processing.tmbundle"]
path = vendor/grammars/processing.tmbundle
url = https://github.com/textmate/processing.tmbundle
[submodule "vendor/grammars/prolog.tmbundle"]
path = vendor/grammars/prolog.tmbundle
url = https://github.com/textmate/prolog.tmbundle
[submodule "vendor/grammars/python-django.tmbundle"]
path = vendor/grammars/python-django.tmbundle
url = https://github.com/textmate/python-django.tmbundle
@@ -655,7 +649,7 @@
url = https://github.com/SRI-CSL/SMT.tmbundle.git
[submodule "vendor/grammars/language-crystal"]
path = vendor/grammars/language-crystal
url = https://github.com/k2b6s9j/language-crystal
url = https://github.com/atom-crystal/language-crystal
[submodule "vendor/grammars/language-xbase"]
path = vendor/grammars/language-xbase
url = https://github.com/hernad/atom-language-harbour
@@ -671,6 +665,27 @@
[submodule "vendor/grammars/st2-zonefile"]
path = vendor/grammars/st2-zonefile
url = https://github.com/sixty4k/st2-zonefile
[submodule "vendor/grammars/sublimeprolog"]
path = vendor/grammars/sublimeprolog
url = https://github.com/alnkpa/sublimeprolog
[submodule "vendor/grammars/sublime-aspectj"]
path = vendor/grammars/sublime-aspectj
url = https://github.com/pchaigno/sublime-aspectj
[submodule "vendor/grammars/sublime-typescript"]
path = vendor/grammars/sublime-typescript
url = https://github.com/Microsoft/TypeScript-Sublime-Plugin
[submodule "vendor/grammars/sublime-pony"]
path = vendor/grammars/sublime-pony
url = https://github.com/CausalityLtd/sublime-pony
[submodule "vendor/grammars/X10"]
path = vendor/grammars/X10
url = git@github.com:x10-lang/x10-highlighting.git
[submodule "vendor/grammars/language-babel"]
path = vendor/grammars/language-babel
url = https://github.com/gandm/language-babel
[submodule "vendor/grammars/Stata.tmbundle"]
path = vendor/grammars/Stata.tmbundle
url = https://github.com/pschumm/Stata.tmbundle
[submodule "vendor/grammars/FreeMarker.tmbundle"]
path = vendor/grammars/FreeMarker.tmbundle
url = https://github.com/freemarker/FreeMarker.tmbundle

View File

@@ -1,6 +1,12 @@
language: ruby
sudo: false
addons:
apt:
packages:
- libicu-dev
- libicu48
before_install: script/travis/before_install
rvm:
- 1.9.3
- 2.0.0
- 2.1
- 2.2

View File

@@ -12,7 +12,7 @@ We try only to add new extensions once they have some usage on GitHub. In most c
To add support for a new extension:
0. Add your extension to the language entry in [`languages.yml`][languages].
0. Add your extension to the language entry in [`languages.yml`][languages], keeping the extensions in alphabetical order.
0. Add at least one sample for your extension to the [samples directory][samples] in the correct subdirectory.
0. Open a pull request, linking to a [GitHub search result](https://github.com/search?utf8=%E2%9C%93&q=extension%3Aboot+NOT+nothack&type=Code&ref=searchresults) showing in-the-wild usage.

View File

@@ -13,11 +13,11 @@ See [Troubleshooting](#troubleshooting) and [`CONTRIBUTING.md`](/CONTRIBUTING.md
![language stats bar](https://cloud.githubusercontent.com/assets/173/5562290/48e24654-8ddf-11e4-8fe7-735b0ce3a0d3.png)
The Language stats bar is built by aggregating the languages of each file in that repository. If it is reporting a language that you don't expect:
The Language stats bar displays languages percentages for the files in the repository. The percentages are calculated based on the bytes of code for each language as reported by the [List Languages](https://developer.github.com/v3/repos/#list-languages) API. If the bar is reporting a language that you don't expect:
0. Click on the name of the language in the stats bar to see a list of the files that are identified as that language.
0. If you see files that you didn't write, consider moving the files into one of the [paths for vendored code](https://github.com/github/linguist/blob/master/lib/linguist/vendor.yml), or use the [manual overrides](#overrides) feature to ignore them.
0. If the files are being misclassified, search for [open issues][issues] to see if anyone else has already reported the issue. Any information you an add, especially links to public repositories, is helpful.
0. If you see files that you didn't write, consider moving the files into one of the [paths for vendored code](/lib/linguist/vendor.yml), or use the [manual overrides](#overrides) feature to ignore them.
0. If the files are being misclassified, search for [open issues][issues] to see if anyone else has already reported the issue. Any information you can add, especially links to public repositories, is helpful.
0. If there are no reported issues of this misclassification, [open an issue][new-issue] and include a link to the repository or a sample of the code that is being misclassified.
## Overrides
@@ -33,9 +33,9 @@ $ cat .gitattributes
*.rb linguist-language=Java
```
Checking code you didn't write, such as JavaScript libraries, into your git repo is a common practice, but this often inflates your project's language stats and may even cause your project to be labeled as another language. By default, Linguist treats all of the paths defined in [lib/linguist/vendor.yml](https://github.com/github/linguist/blob/master/lib/linguist/vendor.yml) as vendored and therefore doesn't include them in the language statistics for a repository. Vendored files are also hidden by default in diffs on github.com.
Checking code you didn't write, such as JavaScript libraries, into your git repo is a common practice, but this often inflates your project's language stats and may even cause your project to be labeled as another language. By default, Linguist treats all of the paths defined in [lib/linguist/vendor.yml](https://github.com/github/linguist/blob/master/lib/linguist/vendor.yml) as vendored and therefore doesn't include them in the language statistics for a repository.
Use the `linguist-vendored` attribute to vendor or un-vendor paths. Please note, overriding the vendored (or un-vendored) status of a file only affects the language statistics for the repository and not the behavior in diffs on github.com.
Use the `linguist-vendored` attribute to vendor or un-vendor paths.
```
$ cat .gitattributes

137
bin/git-linguist Executable file
View File

@@ -0,0 +1,137 @@
#!/usr/bin/env ruby
require 'linguist'
require 'rugged'
require 'optparse'
require 'json'
require 'tmpdir'
require 'zlib'
class GitLinguist
def initialize(path, commit_oid, incremental = true)
@repo_path = path
@commit_oid = commit_oid
@incremental = incremental
end
def linguist
if @commit_oid.nil?
raise "git-linguist must be called with a specific commit OID to perform language computation"
end
repo = Linguist::Repository.new(rugged, @commit_oid)
if @incremental && stats = load_language_stats
old_commit_oid, old_stats = stats
# A cache with NULL oid means that we want to froze
# these language stats in place and stop computing
# them (for performance reasons)
return old_stats if old_commit_oid == NULL_OID
repo.load_existing_stats(old_commit_oid, old_stats)
end
result = yield repo
save_language_stats(@commit_oid, repo.cache)
result
end
def load_language_stats
version, oid, stats = load_cache
if version == LANGUAGE_STATS_CACHE_VERSION && oid && stats
[oid, stats]
end
end
def save_language_stats(oid, stats)
cache = [LANGUAGE_STATS_CACHE_VERSION, oid, stats]
write_cache(cache)
end
def clear_language_stats
File.unlink(cache_file)
end
def disable_language_stats
save_language_stats(NULL_OID, {})
end
protected
NULL_OID = ("0" * 40).freeze
LANGUAGE_STATS_CACHE = 'language-stats.cache'
LANGUAGE_STATS_CACHE_VERSION = "v3:#{Linguist::VERSION}"
def rugged
@rugged ||= Rugged::Repository.bare(@repo_path)
end
def cache_file
File.join(@repo_path, LANGUAGE_STATS_CACHE)
end
def write_cache(object)
return unless File.directory? @repo_path
begin
tmp_path = Dir::Tmpname.make_tmpname(cache_file, nil)
File.open(tmp_path, "wb") do |f|
marshal = Marshal.dump(object)
f.write(Zlib::Deflate.deflate(marshal))
end
File.rename(tmp_path, cache_file)
rescue => e
(File.unlink(tmp_path) rescue nil)
raise e
end
end
def load_cache
marshal = File.open(cache_file, "rb") { |f| Zlib::Inflate.inflate(f.read) }
Marshal.load(marshal)
rescue SystemCallError, ::Zlib::DataError, ::Zlib::BufError, TypeError
nil
end
end
def git_linguist(args)
incremental = true
commit = nil
parser = OptionParser.new do |opts|
opts.banner = "Usage: git-linguist [OPTIONS] stats|breakdown|dump-cache|clear|disable"
opts.on("-f", "--force", "Force a full rescan") { incremental = false }
opts.on("--commit=COMMIT", "Commit to index") { |v| commit = v}
end
parser.parse!(args)
git_dir = `git rev-parse --git-dir`.strip
raise "git-linguist must be ran in a Git repository" unless $?.success?
wrapper = GitLinguist.new(git_dir, commit, incremental)
case args.pop
when "stats"
wrapper.linguist do |linguist|
puts JSON.dump(linguist.languages)
end
when "breakdown"
wrapper.linguist do |linguist|
puts JSON.dump(linguist.breakdown_by_file)
end
when "dump-cache"
puts JSON.dump(wrapper.load_language_stats)
when "clear"
wrapper.clear_language_stats
when "disable"
wrapper.disable_language_stats
else
$stderr.print(parser.help)
exit 1
end
end
git_linguist(ARGV)

View File

@@ -10,8 +10,8 @@ Gem::Specification.new do |s|
s.homepage = "https://github.com/github/linguist"
s.license = "MIT"
s.files = Dir['lib/**/*'] - ['lib/linguist/grammars.rb']
s.executables << 'linguist'
s.files = Dir['lib/**/*'] - ['lib/linguist/grammars.rb'] + ['LICENSE']
s.executables = ['linguist', 'git-linguist']
s.add_dependency 'charlock_holmes', '~> 0.7.3'
s.add_dependency 'escape_utils', '~> 1.1.0'
@@ -24,4 +24,6 @@ Gem::Specification.new do |s|
s.add_development_dependency 'rake'
s.add_development_dependency 'yajl-ruby'
s.add_development_dependency 'color-proximity', '~> 0.2.1'
s.add_development_dependency 'licensee', '6.0.0b1'
end

View File

@@ -42,6 +42,8 @@ vendor/grammars/Docker.tmbundle:
- source.dockerfile
vendor/grammars/Elm.tmLanguage:
- source.elm
vendor/grammars/FreeMarker.tmbundle:
- text.html.ftl
vendor/grammars/G-Code/:
- source.LS
- source.MCPOST
@@ -92,7 +94,7 @@ vendor/grammars/Scalate.tmbundle:
- text.html.ssp
vendor/grammars/Slash.tmbundle:
- text.html.slash
vendor/grammars/Stata.tmbundle:
vendor/grammars/Stata.tmbundle/:
- source.mata
- source.stata
vendor/grammars/Stylus/:
@@ -144,6 +146,8 @@ vendor/grammars/VBDotNetSyntax:
- source.vbnet
vendor/grammars/Vala-TMBundle:
- source.vala
vendor/grammars/X10:
- source.x10
vendor/grammars/abap.tmbundle:
- source.abap
vendor/grammars/actionscript3-tmbundle:
@@ -176,6 +180,9 @@ vendor/grammars/assembly.tmbundle:
- source.x86asm
vendor/grammars/atom-fsharp/:
- source.fsharp
- source.fsharp.fsi
- source.fsharp.fsl
- source.fsharp.fsx
vendor/grammars/atom-language-purescript/:
- source.purescript
vendor/grammars/atom-salt:
@@ -295,8 +302,8 @@ vendor/grammars/io.tmbundle:
vendor/grammars/ioke-outdated:
- source.ioke
vendor/grammars/jade-tmbundle:
- source.jade
- source.pyjade
- text.jade
vendor/grammars/jasmin-sublime:
- source.jasmin
vendor/grammars/java.tmbundle:
@@ -312,6 +319,9 @@ vendor/grammars/json.tmbundle:
- source.json
vendor/grammars/kotlin-sublime-package:
- source.Kotlin
vendor/grammars/language-babel/:
- source.js.jsx
- source.regexp.babel
vendor/grammars/language-clojure:
- source.clojure
vendor/grammars/language-coffee-script:
@@ -345,6 +355,8 @@ vendor/grammars/language-python:
vendor/grammars/language-shellscript:
- source.shell
- text.shell-session
vendor/grammars/language-supercollider:
- source.supercollider
vendor/grammars/language-xbase:
- source.harbour
vendor/grammars/language-yaml:
@@ -432,8 +444,6 @@ vendor/grammars/powershell:
- source.powershell
vendor/grammars/processing.tmbundle:
- source.processing
vendor/grammars/prolog.tmbundle:
- source.prolog
vendor/grammars/protobuf-tmbundle:
- source.protobuf
vendor/grammars/puppet-textmate-bundle:
@@ -484,8 +494,6 @@ vendor/grammars/sublime-aspectj/:
- source.aspectj
vendor/grammars/sublime-befunge:
- source.befunge
vendor/grammars/sublime-better-typescript:
- source.ts
vendor/grammars/sublime-bsv:
- source.bsv
vendor/grammars/sublime-cirru:
@@ -509,6 +517,8 @@ vendor/grammars/sublime-nix:
vendor/grammars/sublime-opal/:
- source.opal
- source.opalsysdefs
vendor/grammars/sublime-pony:
- source.pony
vendor/grammars/sublime-robot-plugin:
- text.robot
vendor/grammars/sublime-rust:
@@ -524,6 +534,9 @@ vendor/grammars/sublime-text-ox/:
- source.ox
vendor/grammars/sublime-text-pig-latin/:
- source.pig_latin
vendor/grammars/sublime-typescript/:
- source.ts
- source.tsx
vendor/grammars/sublime-varnish:
- source.varnish.vcl
vendor/grammars/sublime_cobol:
@@ -534,6 +547,9 @@ vendor/grammars/sublime_cobol:
vendor/grammars/sublime_man_page_support:
- source.man
- text.groff
vendor/grammars/sublimeprolog/:
- source.prolog
- source.prolog.eclipse
vendor/grammars/sublimetext-cuda-cpp:
- source.cuda-c++
vendor/grammars/swift.tmbundle:

73
lib/linguist/blob.rb Normal file
View File

@@ -0,0 +1,73 @@
require 'linguist/blob_helper'
module Linguist
# A Blob is a wrapper around the content of a file to make it quack
# like a Grit::Blob. It provides the basic interface: `name`,
# `data`, `path` and `size`.
class Blob
include BlobHelper
# Public: Initialize a new Blob.
#
# path - A path String (does not necessarily exists on the file system).
# content - Content of the file.
#
# Returns a Blob.
def initialize(path, content)
@path = path
@content = content
end
# Public: Filename
#
# Examples
#
# Blob.new("/path/to/linguist/lib/linguist.rb", "").path
# # => "/path/to/linguist/lib/linguist.rb"
#
# Returns a String
attr_reader :path
# Public: File name
#
# Returns a String
def name
File.basename(@path)
end
# Public: File contents.
#
# Returns a String.
def data
@content
end
# Public: Get byte size
#
# Returns an Integer.
def size
@content.bytesize
end
# Public: Get file extension.
#
# Returns a String.
def extension
extensions.last || ""
end
# Public: Return an array of the file extensions
#
# >> Linguist::Blob.new("app/views/things/index.html.erb").extensions
# => [".html.erb", ".erb"]
#
# Returns an Array
def extensions
basename, *segments = name.downcase.split(".")
segments.map.with_index do |segment, index|
"." + segments[index..-1].join(".")
end
end
end
end

View File

@@ -1,10 +1,11 @@
require 'linguist/blob_helper'
require 'linguist/blob'
module Linguist
# A FileBlob is a wrapper around a File object to make it quack
# like a Grit::Blob. It provides the basic interface: `name`,
# `data`, `path` and `size`.
class FileBlob
class FileBlob < Blob
include BlobHelper
# Public: Initialize a new FileBlob from a path
@@ -18,20 +19,6 @@ module Linguist
@path = base_path ? path.sub("#{base_path}/", '') : path
end
# Public: Filename
#
# Examples
#
# FileBlob.new("/path/to/linguist/lib/linguist.rb").path
# # => "/path/to/linguist/lib/linguist.rb"
#
# FileBlob.new("/path/to/linguist/lib/linguist.rb",
# "/path/to/linguist").path
# # => "lib/linguist.rb"
#
# Returns a String
attr_reader :path
# Public: Read file permissions
#
# Returns a String like '100644'
@@ -39,13 +26,6 @@ module Linguist
File.stat(@fullpath).mode.to_s(8)
end
# Public: File name
#
# Returns a String
def name
File.basename(@fullpath)
end
# Public: Read file contents.
#
# Returns a String.
@@ -59,26 +39,5 @@ module Linguist
def size
File.size(@fullpath)
end
# Public: Get file extension.
#
# Returns a String.
def extension
extensions.last || ""
end
# Public: Return an array of the file extensions
#
# >> Linguist::FileBlob.new("app/views/things/index.html.erb").extensions
# => [".html.erb", ".erb"]
#
# Returns an Array
def extensions
basename, *segments = name.downcase.split(".")
segments.map.with_index do |segment, index|
"." + segments[index..-1].join(".")
end
end
end
end

View File

@@ -71,7 +71,8 @@ module Linguist
generated_jni_header? ||
vcr_cassette? ||
generated_module? ||
generated_unity3d_meta?
generated_unity3d_meta? ||
generated_racc?
end
# Internal: Is the blob an Xcode file?
@@ -241,22 +242,26 @@ module Linguist
return lines[0].include?("Code generated by")
end
PROTOBUF_EXTENSIONS = ['.py', '.java', '.h', '.cc', '.cpp']
# Internal: Is the blob a C++, Java or Python source file generated by the
# Protocol Buffer compiler?
#
# Returns true of false.
def generated_protocol_buffer?
return false unless ['.py', '.java', '.h', '.cc', '.cpp'].include?(extname)
return false unless PROTOBUF_EXTENSIONS.include?(extname)
return false unless lines.count > 1
return lines[0].include?("Generated by the protocol buffer compiler. DO NOT EDIT!")
end
APACHE_THRIFT_EXTENSIONS = ['.rb', '.py', '.go', '.js', '.m', '.java', '.h', '.cc', '.cpp']
# Internal: Is the blob generated by Apache Thrift compiler?
#
# Returns true or false
def generated_apache_thrift?
return false unless ['.rb', '.py', '.go', '.js', '.m', '.java', '.h', '.cc', '.cpp'].include?(extname)
return false unless APACHE_THRIFT_EXTENSIONS.include?(extname)
return false unless lines.count > 1
return lines[0].include?("Autogenerated by Thrift Compiler") || lines[1].include?("Autogenerated by Thrift Compiler")
@@ -355,5 +360,18 @@ module Linguist
return false unless lines.count > 1
return lines[0].include?("fileFormatVersion: ")
end
# Internal: Is this a Racc-generated file?
#
# A Racc-generated file contains:
# # This file is automatically generated by Racc x.y.z
# on the third line.
#
# Return true or false
def generated_racc?
return false unless extname == '.rb'
return false unless lines.count > 2
return lines[2].start_with?("# This file is automatically generated by Racc")
end
end
end

View File

@@ -33,7 +33,7 @@ module Linguist
#
# Examples
#
# disambiguate "Perl", "Prolog" do |data|
# disambiguate ".pm" do |data|
# if data.include?("use strict")
# Language["Perl"]
# elsif /^[^#]+:-/.match(data)
@@ -56,7 +56,8 @@ module Linguist
# Internal: Check if this heuristic matches the candidate languages.
def matches?(filename)
@extensions.any? { |ext| filename.downcase.end_with?(ext) }
filename = filename.downcase
@extensions.any? { |ext| filename.end_with?(ext) }
end
# Internal: Perform the heuristic
@@ -65,7 +66,17 @@ module Linguist
end
# Common heuristics
ObjectiveCRegex = /^[ \t]*@(interface|class|protocol|property|end|synchronised|selector|implementation)\b/
ObjectiveCRegex = /^\s*(@(interface|class|protocol|property|end|synchronised|selector|implementation)\b|#import\s+.+\.h[">])/
disambiguate ".asc" do |data|
if /^(----[- ]BEGIN|ssh-(rsa|dss)) /.match(data)
Language["Public Key"]
elsif /^[=-]+(\s|\n)|{{[A-Za-z]/.match(data)
Language["AsciiDoc"]
elsif /^(\/\/.+|((import|export)\s+)?(function|int|float|char)\s+((room|repeatedly|on|game)_)?([A-Za-z]+[A-Za-z_0-9]+)\s*[;\(])/.match(data)
Language["AGS Script"]
end
end
disambiguate ".bb" do |data|
if /^\s*; /.match(data) || data.include?("End Function")
@@ -75,67 +86,9 @@ module Linguist
end
end
disambiguate ".cs" do |data|
if /![\w\s]+methodsFor: /.match(data)
Language["Smalltalk"]
elsif /^\s*namespace\s*[\w\.]+\s*{/.match(data) || /^\s*\/\//.match(data)
Language["C#"]
end
end
disambiguate ".h" do |data|
if ObjectiveCRegex.match(data)
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) ||
/^\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++"]
end
end
disambiguate ".pl" do |data|
if /^(use v6|(my )?class|module)/.match(data)
Language["Perl6"]
elsif /use strict|use\s+v?5\./.match(data)
Language["Perl"]
elsif /^[^#]+:-/.match(data)
Language["Prolog"]
end
end
disambiguate ".pm" do |data|
if /^(use v6|(my )?class|module)/.match(data)
Language["Perl6"]
elsif /use strict|use\s+v?5\./.match(data)
Language["Perl"]
end
end
disambiguate ".ecl" do |data|
if /^[^#]+:-/.match(data)
Language["Prolog"]
elsif data.include?(":=")
Language["ECL"]
end
end
disambiguate ".pro" do |data|
if /^[^#]+:-/.match(data)
Language["Prolog"]
elsif data.include?("last_client=")
Language["INI"]
elsif data.include?("HEADERS") && data.include?("SOURCES")
Language["QMake"]
elsif /^\s*function[ \w,]+$/.match(data)
Language["IDL"]
end
end
disambiguate ".tst" do |data|
if (data.include?("gap> "))
Language["GAP"]
# Heads up - we don't usually write heuristics like this (with no regex match)
else
Language["Scilab"]
disambiguate ".ch" do |data|
if /^\s*#\s*(if|ifdef|ifndef|define|command|xcommand|translate|xtranslate|include|pragma|undef)\b/i.match(data)
Language["xBase"]
end
end
@@ -149,40 +102,50 @@ module Linguist
end
end
disambiguate ".php" do |data|
if data.include?("<?hh")
Language["Hack"]
elsif /<?[^h]/.match(data)
Language["PHP"]
disambiguate ".cs" do |data|
if /![\w\s]+methodsFor: /.match(data)
Language["Smalltalk"]
elsif /^\s*namespace\s*[\w\.]+\s*{/.match(data) || /^\s*\/\//.match(data)
Language["C#"]
end
end
disambiguate ".sc" do |data|
if /\^(this|super)\./.match(data) || /^\s*(\+|\*)\s*\w+\s*{/.match(data) || /^\s*~\w+\s*=\./.match(data)
Language["SuperCollider"]
elsif /^\s*import (scala|java)\./.match(data) || /^\s*val\s+\w+\s*=/.match(data) || /^\s*class\b/.match(data)
Language["Scala"]
disambiguate ".d" do |data|
if /^module /.match(data)
Language["D"]
elsif /^((dtrace:::)?BEGIN|provider |#pragma (D (option|attributes)|ident)\s)/.match(data)
Language["DTrace"]
elsif /(\/.*:( .* \\)$| : \\$|^ : |: \\$)/.match(data)
Language["Makefile"]
end
end
disambiguate ".asc" do |data|
if /^(----[- ]BEGIN|ssh-(rsa|dss)) /.match(data)
Language["Public Key"]
elsif /^[=-]+(\s|\n)|{{[A-Za-z]/.match(data)
Language["AsciiDoc"]
elsif /^(\/\/.+|((import|export)\s+)?(function|int|float|char)\s+((room|repeatedly|on|game)_)?([A-Za-z]+[A-Za-z_0-9]+)\s*[;\(])/.match(data)
Language["AGS Script"]
disambiguate ".ecl" do |data|
if /^[^#]+:-/.match(data)
Language["ECLiPSe"]
elsif data.include?(":=")
Language["ECL"]
end
end
disambiguate ".for", ".f" do |data|
if /^: /.match(data)
Language["Forth"]
elsif /^([c*][^a-z]| (subroutine|program)\s|\s*!)/i.match(data)
elsif /^([c*][^abd-z]| (subroutine|program|end)\s|\s*!)/i.match(data)
Language["FORTRAN"]
end
end
disambiguate ".fr" do |data|
if /^(: |also |new-device|previous )/.match(data)
Language["Forth"]
elsif /^\s*(import|module|package|data|type) /.match(data)
Language["Frege"]
else
Language["Text"]
end
end
disambiguate ".fs" do |data|
if /^(: |new-device)/.match(data)
Language["Forth"]
@@ -195,6 +158,47 @@ module Linguist
end
end
disambiguate ".gs" do |data|
Language["Gosu"] if /^uses java\./.match(data)
end
disambiguate ".h" do |data|
if ObjectiveCRegex.match(data)
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) ||
/^\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++"]
end
end
disambiguate ".l" do |data|
if /\(def(un|macro)\s/.match(data)
Language["Common Lisp"]
elsif /^(%[%{}]xs|<.*>)/.match(data)
Language["Lex"]
elsif /^\.[a-z][a-z](\s|$)/i.match(data)
Language["Groff"]
elsif /^\((de|class|rel|code|data|must)\s/.match(data)
Language["PicoLisp"]
end
end
disambiguate ".ls" do |data|
if /^\s*package\s*[\w\.\/\*\s]*\s*{/.match(data)
Language["LoomScript"]
else
Language["LiveScript"]
end
end
disambiguate ".lsp", ".lisp" do |data|
if /^\s*\((defun|in-package|defpackage) /i.match(data)
Language["Common Lisp"]
elsif /^\s*\(define /.match(data)
Language["NewLisp"]
end
end
disambiguate ".m" do |data|
if ObjectiveCRegex.match(data)
Language["Objective-C"]
@@ -213,41 +217,113 @@ module Linguist
end
end
disambiguate ".gs" do |data|
Language["Gosu"] if /^uses java\./.match(data)
end
disambiguate ".ls" do |data|
if /^\s*package\s*[\w\.\/\*\s]*\s*{/.match(data)
Language["LoomScript"]
else
Language["LiveScript"]
disambiguate ".ml" do |data|
if /(^\s*module)|let rec |match\s+(\S+\s)+with/.match(data)
Language["OCaml"]
elsif /=> |case\s+(\S+\s)+of/.match(data)
Language["Standard ML"]
end
end
disambiguate ".lsp", ".lisp" do |data|
if /^\s*\((defun|in-package|defpackage) /i.match(data)
Language["Common Lisp"]
elsif /^\s*\(define /.match(data)
disambiguate ".mod" do |data|
if data.include?('<!ENTITY ')
Language["XML"]
elsif /MODULE\s\w+\s*;/i.match(data) || /^\s*END \w+;$/i.match(data)
Language["Modula-2"]
else
[Language["Linux Kernel Module"], Language["AMPL"]]
end
end
disambiguate ".ms" do |data|
if /^[.'][a-z][a-z](\s|$)/i.match(data)
Language["Groff"]
elsif /((^|\s)move?[. ])|\.(include|globa?l)\s/.match(data)
Language["GAS"]
end
end
disambiguate ".n" do |data|
if /^[.']/.match(data)
Language["Groff"]
elsif /^(module|namespace|using)\s/.match(data)
Language["Nemerle"]
end
end
disambiguate ".ncl" do |data|
if data.include?("THE_TITLE")
Language["Text"]
end
end
disambiguate ".nl" do |data|
if /^(b|g)[0-9]+ /.match(data)
Language["NL"]
else
Language["NewLisp"]
end
end
disambiguate ".ts" do |data|
if data.include?("<TS ")
Language["XML"]
else
Language["TypeScript"]
disambiguate ".php" do |data|
if data.include?("<?hh")
Language["Hack"]
elsif /<?[^h]/.match(data)
Language["PHP"]
end
end
disambiguate ".fr" do |data|
if /^(: |also |new-device|previous )/.match(data)
Language["Forth"]
elsif /^\s*(import|module|package|data|type) /.match(data)
Language["Frege"]
else
Language["Text"]
disambiguate ".pl" do |data|
if /^(use v6|(my )?class|module)/.match(data)
Language["Perl6"]
elsif /use strict|use\s+v?5\./.match(data)
Language["Perl"]
elsif /^[^#]+:-/.match(data)
Language["Prolog"]
end
end
disambiguate ".pm", ".t" do |data|
if /^(use v6|(my )?class|module)/.match(data)
Language["Perl6"]
elsif /use strict|use\s+v?5\./.match(data)
Language["Perl"]
end
end
disambiguate ".pro" do |data|
if /^[^#]+:-/.match(data)
Language["Prolog"]
elsif data.include?("last_client=")
Language["INI"]
elsif data.include?("HEADERS") && data.include?("SOURCES")
Language["QMake"]
elsif /^\s*function[ \w,]+$/.match(data)
Language["IDL"]
end
end
disambiguate ".r" do |data|
if /\bRebol\b/i.match(data)
Language["Rebol"]
elsif data.include?("<-")
Language["R"]
end
end
disambiguate ".rs" do |data|
if /^(use |fn |mod |pub |macro_rules|impl|#!?\[)/.match(data)
Language["Rust"]
elsif /#include|#pragma\s+(rs|version)|__attribute__/.match(data)
Language["RenderScript"]
end
end
disambiguate ".sc" do |data|
if /\^(this|super)\./.match(data) || /^\s*(\+|\*)\s*\w+\s*{/.match(data) || /^\s*~\w+\s*=\./.match(data)
Language["SuperCollider"]
elsif /^\s*import (scala|java)\./.match(data) || /^\s*val\s+\w+\s*=/.match(data) || /^\s*class\b/.match(data)
Language["Scala"]
end
end
@@ -267,95 +343,20 @@ module Linguist
end
end
disambiguate ".d" do |data|
if /^module /.match(data)
Language["D"]
elsif /^((dtrace:::)?BEGIN|provider |#pragma (D (option|attributes)|ident)\s)/.match(data)
Language["DTrace"]
elsif /(\/.*:( .* \\)$| : \\$|^ : |: \\$)/.match(data)
Language["Makefile"]
end
end
disambiguate ".ml" do |data|
if /(^\s*module)|let rec |match\s+(\S+\s)+with/.match(data)
Language["OCaml"]
elsif /=> |case\s+(\S+\s)+of/.match(data)
Language["Standard ML"]
end
end
disambiguate ".mod" do |data|
if data.include?('<!ENTITY ')
disambiguate ".ts" do |data|
if data.include?("<TS ")
Language["XML"]
elsif /MODULE\s\w+\s*;/i.match(data) || /^\s*END \w+;$/i.match(data)
Language["Modula-2"]
else
[Language["Linux Kernel Module"], Language["AMPL"]]
Language["TypeScript"]
end
end
disambiguate ".ncl" do |data|
if data.include?("THE_TITLE")
Language["Text"]
end
end
disambiguate ".nl" do |data|
if /^(b|g)[0-9]+ /.match(data)
Language["NL"]
disambiguate ".tst" do |data|
if (data.include?("gap> "))
Language["GAP"]
# Heads up - we don't usually write heuristics like this (with no regex match)
else
Language["NewLisp"]
end
end
disambiguate ".rs" do |data|
if /^(use |fn |mod |pub |macro_rules|impl|#!?\[)/.match(data)
Language["Rust"]
elsif /#include|#pragma\s+(rs|version)|__attribute__/.match(data)
Language["RenderScript"]
end
end
disambiguate ".l" do |data|
if /\(def(un|macro)\s/.match(data)
Language["Common Lisp"]
elsif /^(%[%{}]xs|<.*>)/.match(data)
Language["Lex"]
elsif /^\.[a-z][a-z](\s|$)/i.match(data)
Language["Groff"]
elsif /^\((de|class|rel|code|data|must)\s/.match(data)
Language["PicoLisp"]
end
end
disambiguate ".n" do |data|
if /^[.']/.match(data)
Language["Groff"]
elsif /^(module|namespace|using)\s/.match(data)
Language["Nemerle"]
end
end
disambiguate ".ms" do |data|
if /^[.'][a-z][a-z](\s|$)/i.match(data)
Language["Groff"]
elsif /((^|\s)move?[. ])|\.(include|globa?l)\s/.match(data)
Language["GAS"]
end
end
disambiguate ".ch" do |data|
if /^\s*#\s*(if|ifdef|ifndef|define|command|xcommand|translate|xtranslate|include|pragma|undef)\b/i.match(data)
Language["xBase"]
end
end
disambiguate ".r" do |data|
if /\bRebol\b/i.match(data)
Language["Rebol"]
elsif data.include?("<-")
Language["R"]
Language["Scilab"]
end
end
end

View File

@@ -8,7 +8,8 @@
# Use "text" if a mode does not exist.
# wrap - Boolean wrap to enable line wrapping (default: false)
# extensions - An Array of associated extensions (the first one is
# considered the primary extension)
# considered the primary extension, the others should be
# listed alphabetically)
# interpreters - An Array of associated interpreters
# searchable - Boolean flag to enable searching (defaults to true)
# search_term - Deprecated: Some languages maybe indexed under a
@@ -392,6 +393,7 @@ C#:
- csharp
extensions:
- .cs
- .cake
- .cshtml
- .csx
@@ -567,6 +569,7 @@ CoffeeScript:
extensions:
- .coffee
- ._coffee
- .cake
- .cjsx
- .cson
- .iced
@@ -719,7 +722,7 @@ Cython:
D:
type: programming
color: "#fcd46d"
color: "#ba595e"
extensions:
- .d
- .di
@@ -843,6 +846,14 @@ ECL:
tm_scope: none
ace_mode: text
ECLiPSe:
type: programming
group: prolog
extensions:
- .ecl
tm_scope: source.prolog.eclipse
ace_mode: prolog
Eagle:
type: markup
color: "#814C05"
@@ -1003,6 +1014,7 @@ Formatted:
type: data
extensions:
- .for
- .eam.fs
tm_scope: none
ace_mode: text
@@ -1020,6 +1032,16 @@ Forth:
- .fs
ace_mode: forth
FreeMarker:
type: programming
color: "#0050b2"
aliases:
- ftl
extensions:
- .ftl
tm_scope: text.html.ftl
ace_mode: ftl
Frege:
type: programming
color: "#00cafe"
@@ -1309,11 +1331,22 @@ HTML+Django:
- .mustache
- .jinja
aliases:
- django
- html+django/jinja
- html+jinja
- htmldjango
ace_mode: django
HTML+EEX:
type: markup
tm_scope: text.html.elixir
group: HTML
aliases:
- eex
extensions:
- .eex
ace_mode: text
HTML+ERB:
type: markup
tm_scope: text.html.erb
@@ -1323,7 +1356,7 @@ HTML+ERB:
extensions:
- .erb
- .erb.deface
ace_mode: html_ruby
ace_mode: text
HTML+PHP:
type: markup
@@ -1359,6 +1392,7 @@ Haml:
Handlebars:
type: markup
color: "#01a9d6"
group: HTML
aliases:
- hbs
- htmlbars
@@ -1537,7 +1571,9 @@ JSON:
searchable: false
extensions:
- .json
- .geojson
- .lock
- .topojson
filenames:
- .jshintrc
- composer.lock
@@ -1565,12 +1601,20 @@ JSONiq:
- .jq
tm_scope: source.jq
JSX:
type: programming
group: JavaScript
extensions:
- .jsx
tm_scope: source.js.jsx
ace_mode: javascript
Jade:
group: HTML
type: markup
extensions:
- .jade
tm_scope: source.jade
tm_scope: text.jade
ace_mode: jade
Jasmin:
@@ -1615,10 +1659,10 @@ JavaScript:
- .gs
- .jake
- .jsb
- .jscad
- .jsfl
- .jsm
- .jss
- .jsx
- .njs
- .pac
- .sjs
@@ -1662,6 +1706,7 @@ KiCad:
type: programming
extensions:
- .sch
- .brd
- .kicad_pcb
tm_scope: none
ace_mode: text
@@ -1711,6 +1756,7 @@ LSL:
ace_mode: lsl
extensions:
- .lsl
- .lslp
interpreters:
- lsl
color: '#3d9970'
@@ -2043,6 +2089,14 @@ Mercury:
tm_scope: source.mercury
ace_mode: prolog
Metal:
type: programming
color: "#8f14e9"
extensions:
- .metal
tm_scope: source.c++
ace_mode: c_cpp
MiniD: # Legacy
type: programming
searchable: false
@@ -2118,7 +2172,7 @@ Myghty:
NCL:
type: programming
color: #28431f
color: "#28431f"
extensions:
- .ncl
tm_scope: source.ncl
@@ -2421,6 +2475,7 @@ PHP:
- .php3
- .php4
- .php5
- .phps
- .phpt
filenames:
- Phakefile
@@ -2434,8 +2489,10 @@ PLSQL:
type: programming
ace_mode: sql
tm_scope: source.plsql.oracle
color: "#dad8d8"
extensions:
- .pls
- .pck
- .pkb
- .pks
- .plb
@@ -2552,6 +2609,13 @@ Perl6:
tm_scope: source.perl.6
ace_mode: perl
Pickle:
type: data
extensions:
- .pkl
tm_scope: none
ace_mode: text
PicoLisp:
type: programming
extensions:
@@ -2596,6 +2660,13 @@ PogoScript:
tm_scope: source.pogoscript
ace_mode: text
Pony:
type: programming
extensions:
- .pony
tm_scope: source.pony
ace_mode: text
PostScript:
type: markup
extensions:
@@ -2628,11 +2699,11 @@ Prolog:
color: "#74283c"
extensions:
- .pl
- .ecl
- .pro
- .prolog
interpreters:
- swipl
tm_scope: source.prolog
ace_mode: prolog
Propeller Spin:
@@ -2770,7 +2841,7 @@ R:
ace_mode: r
RAML:
type: data
type: markup
ace_mode: yaml
tm_scope: source.yaml
color: "#77d9fb"
@@ -2813,7 +2884,7 @@ RMarkdown:
ace_mode: markdown
extensions:
- .rmd
tm_scope: none
tm_scope: source.gfm
Racket:
type: programming
@@ -3087,7 +3158,7 @@ Sass:
Scala:
type: programming
ace_mode: scala
color: "#7dd3b0"
color: "#DC322F"
extensions:
- .scala
- .sbt
@@ -3276,9 +3347,12 @@ SuperCollider:
type: programming
color: "#46390b"
extensions:
- .scd
- .sc
tm_scope: none
- .scd
interpreters:
- sclang
- scsynth
tm_scope: source.supercollider
ace_mode: text
Swift:
@@ -3421,6 +3495,7 @@ TypeScript:
- ts
extensions:
- .ts
- .tsx
tm_scope: source.ts
ace_mode: typescript
@@ -3559,6 +3634,16 @@ WebIDL:
tm_scope: source.webidl
ace_mode: text
X10:
type: programming
aliases:
- xten
ace_mode: text
extensions:
- .x10
color: "#4B6BEF"
tm_scope: source.x10
XC:
type: programming
color: "#99DA07"
@@ -3581,6 +3666,7 @@ XML:
- .ccxml
- .clixml
- .cproject
- .csl
- .csproj
- .ct
- .dita
@@ -3596,6 +3682,7 @@ XML:
- .iml
- .ivy
- .jelly
- .jsproj
- .kml
- .launch
- .mdpolicy
@@ -3626,6 +3713,7 @@ XML:
- .tmSnippet
- .tmTheme
- .ts
- .tsx
- .ui
- .urdf
- .vbproj

View File

@@ -4,7 +4,11 @@ require 'rugged'
module Linguist
class LazyBlob
GIT_ATTR = ['linguist-documentation', 'linguist-language', 'linguist-vendored']
GIT_ATTR = ['linguist-documentation',
'linguist-language',
'linguist-vendored',
'linguist-generated']
GIT_ATTR_OPTS = { :priority => [:index], :skip_system => true }
GIT_ATTR_FLAGS = Rugged::Repository::Attributes.parse_opts(GIT_ATTR_OPTS)
@@ -31,14 +35,6 @@ module Linguist
name, GIT_ATTR, GIT_ATTR_FLAGS)
end
def vendored?
if attr = git_attributes['linguist-vendored']
return boolean_attribute(attr)
else
return super
end
end
def documentation?
if attr = git_attributes['linguist-documentation']
boolean_attribute(attr)
@@ -47,6 +43,22 @@ module Linguist
end
end
def generated?
if attr = git_attributes['linguist-generated']
boolean_attribute(attr)
else
super
end
end
def vendored?
if attr = git_attributes['linguist-vendored']
return boolean_attribute(attr)
else
super
end
end
def language
return @language if defined?(@language)
@@ -67,6 +79,10 @@ module Linguist
@size
end
def cleanup!
@data.clear if @data
end
protected
# Returns true if the attribute is present and not the string "false".

View File

@@ -126,12 +126,13 @@ module Linguist
end
protected
MAX_TREE_SIZE = 100_000
def compute_stats(old_commit_oid, cache = nil)
return {} if current_tree.count_recursive(MAX_TREE_SIZE) >= MAX_TREE_SIZE
old_tree = old_commit_oid && Rugged::Commit.lookup(repository, old_commit_oid).tree
read_index
diff = Rugged::Tree.diff(repository, old_tree, current_tree)
# Clear file map and fetch full diff if any .gitattributes files are changed
@@ -157,8 +158,11 @@ module Linguist
blob = Linguist::LazyBlob.new(repository, delta.new_file[:oid], new, mode.to_s(8))
next unless blob.include_in_language_stats?
file_map[new] = [blob.language.group.name, blob.size]
if blob.include_in_language_stats?
file_map[new] = [blob.language.group.name, blob.size]
end
blob.cleanup!
end
end

View File

@@ -86,13 +86,13 @@ module Linguist
if s.peek(1) == "\""
s.getch
else
s.skip_until(/[^\\]"/)
s.skip_until(/(?<!\\)"/)
end
elsif s.scan(/'/)
if s.peek(1) == "'"
s.getch
else
s.skip_until(/[^\\]'/)
s.skip_until(/(?<!\\)'/)
end
# Skip number literals

View File

@@ -78,6 +78,9 @@
# Haxelib projects often contain a neko bytecode file named run.n
- run.n$
# Bootstrap Datepicker
- bootstrap-datepicker/
## Commonly Bundled JavaScript frameworks ##
# jQuery
@@ -88,6 +91,34 @@
- (^|/)jquery\-ui(\-\d\.\d+(\.\d+)?)?(\.\w+)?\.(js|css)$
- (^|/)jquery\.(ui|effects)\.([^.]*)\.(js|css)$
# jQuery Gantt
- jquery.fn.gantt.js
# jQuery fancyBox
- jquery.fancybox.(js|css)
# Fuel UX
- fuelux.js
# jQuery File Upload
- (^|/)jquery\.fileupload(-\w+)?\.js$
# Slick
- (^|/)slick\.\w+.js$
# Leaflet plugins
- (^|/)Leaflet\.Coordinates-\d+\.\d+\.\d+\.src\.js$
- leaflet.draw-src.js
- leaflet.draw.css
- Control.FullScreen.css
- Control.FullScreen.js
- leaflet.spin.js
- wicket-leaflet.js
# Sublime Text workspace files
- .sublime-project
- .sublime-workspace
# Prototype
- (^|/)prototype(.*)\.js$
- (^|/)effects\.js$
@@ -122,7 +153,7 @@
- (^|/)Chart\.js$
# Codemirror
- (^|/)[Cc]ode[Mm]irror/(lib|mode|theme|addon|keymap|demo)
- (^|/)[Cc]ode[Mm]irror/(\d+\.\d+/)?(lib|mode|theme|addon|keymap|demo)
# SyntaxHighlighter - http://alexgorbatchev.com/
- (^|/)shBrush([^.]*)\.js$
@@ -164,6 +195,11 @@
## Obj-C ##
# Xcode
- \.xctemplate/
- \.imageset/
# Carthage
- ^Carthage/
@@ -230,6 +266,7 @@
# Test fixtures
- ^[Tt]ests?/fixtures/
- ^[Ss]pecs?/fixtures/
# PhoneGap/Cordova
- (^|/)cordova([^.]*)\.js$

View File

@@ -1,3 +1,3 @@
module Linguist
VERSION = "4.5.14"
VERSION = "4.7.2"
end

86
samples/C#/build.cake Normal file
View File

@@ -0,0 +1,86 @@
///////////////////////////////////////////////////////////////////////////////
// ARGUMENTS
///////////////////////////////////////////////////////////////////////////////
var target = Argument<string>("target", "Default");
var configuration = Argument<string>("configuration", "Release");
///////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
///////////////////////////////////////////////////////////////////////////////
var solutions = GetFiles("./**/*.sln");
var solutionPaths = solutions.Select(solution => solution.GetDirectory());
///////////////////////////////////////////////////////////////////////////////
// SETUP / TEARDOWN
///////////////////////////////////////////////////////////////////////////////
Setup(() =>
{
// Executed BEFORE the first task.
Information("Running tasks...");
});
Teardown(() =>
{
// Executed AFTER the last task.
Information("Finished running tasks.");
});
///////////////////////////////////////////////////////////////////////////////
// TASK DEFINITIONS
///////////////////////////////////////////////////////////////////////////////
Task("Clean")
.Does(() =>
{
// Clean solution directories.
foreach(var path in solutionPaths)
{
Information("Cleaning {0}", path);
CleanDirectories(path + "/**/bin/" + configuration);
CleanDirectories(path + "/**/obj/" + configuration);
}
});
Task("Restore")
.Does(() =>
{
// Restore all NuGet packages.
foreach(var solution in solutions)
{
Information("Restoring {0}...", solution);
NuGetRestore(solution);
}
});
Task("Build")
.IsDependentOn("Clean")
.IsDependentOn("Restore")
.Does(() =>
{
// Build all solutions.
foreach(var solution in solutions)
{
Information("Building {0}", solution);
MSBuild(solution, settings =>
settings.SetPlatformTarget(PlatformTarget.MSIL)
.WithProperty("TreatWarningsAsErrors","true")
.WithTarget("Build")
.SetConfiguration(configuration));
}
});
///////////////////////////////////////////////////////////////////////////////
// TARGETS
///////////////////////////////////////////////////////////////////////////////
Task("Default")
.IsDependentOn("Build");
///////////////////////////////////////////////////////////////////////////////
// EXECUTION
///////////////////////////////////////////////////////////////////////////////
RunTarget(target);

View File

@@ -0,0 +1,17 @@
fs = require 'fs'
{print} = require 'sys'
{spawn} = require 'child_process'
build = (callback) ->
coffee = spawn 'coffee', ['-c', '-o', '.', '.']
coffee.stderr.on 'data', (data) ->
process.stderr.write data.toString()
coffee.stdout.on 'data', (data) ->
print data.toString()
coffee.on 'exit', (code) ->
callback?() if code is 0
task 'build', 'Build from source', ->
build()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
<#import "layout.ftl" as layout>
<#assign results = [
{
"title": "Example Result",
"description": "Lorem ipsum dolor sit amet, pede id pellentesque, sollicitudin turpis sed in sed sed, libero dictum."
}
] />
<@layout.page title="FreeMarker Example">
<#if results?size == 0>
There were no results.
<#else>
<ul>
<#list results as result>
<li>
<strong>${result.title}</strong>
<p>${result.description}</p>
</li>
</#list>
</ul>
</#if>
<#-- This is a FreeMarker comment -->
<@currentTime />
</@layout.page>
<#macro currentTime>
${.now?string.full}
</#macro>

View File

@@ -0,0 +1,32 @@
<#ftl strip_text=true />
<#macro page title>
<!doctype html>
<html lang="${.lang}">
<head>
<title>${title}</title>
<@metaTags />
</head>
<body>
<#nested />
<@footer />
</body>
</html>
</#macro>
<#---
Default meta tags
-->
<#macro metaTags>
<#compress>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="format-detection" content="telephone=no">
</#compress>
</#macro>
<#macro footer>
<p>This page is using FreeMarker v${.version}</p>
</#macro>

View File

@@ -0,0 +1,26 @@
<h1>Listing Books</h1>
<table>
<tr>
<th>Title</th>
<th>Summary</th>
<th></th>
<th></th>
<th></th>
</tr>
<%= for book <- @books do %>
<tr>
<%# comment %>
<td><%= book.title %></td>
<td><%= book.content %></td>
<td><%= link "Show", to: book_path(@conn, :show, book) %></td>
<td><%= link "Edit", to: book_path(@conn, :edit, book) %></td>
<td><%= link "Delete", to: book_path(@conn, :delete, book), method: :delete, data: [confirm: "Are you sure?"] %></td>
</tr>
<% end %>
</table>
<br />
<%= link "New book", to: book_path(@conn, :new) %>

82
samples/JSON/geo.geojson Normal file
View File

@@ -0,0 +1,82 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "Australia Post - North Ryde BC",
"geo": [-33.787792, 151.13288],
"streetAddress": "11 Waterloo Road",
"addressLocality": "Macquarie Park",
"addressRegion": "New South Wales",
"addressCountry": "Australia",
"postalCode": "2113"
},
"geometry": {
"type": "Point",
"coordinates": [151.13288, -33.787792, 0]
}
},
{
"type": "Feature",
"properties": {
"name": "George Weston Foods Limited",
"geo": [-37.8263884, 144.9105381],
"streetAddress": "Level 3, 187 Todd Road",
"addressLocality": "Port Melbourne",
"addressRegion": "Victoria",
"addressCountry": "Australia",
"postalCode": "3207"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[144.9097088901841, -37.82622654171794, 0],
[144.9099724266943, -37.82679388891783, 0],
[144.9110127325916, -37.82651526396403, 0],
[144.9112227645738, -37.82655667152123, 0],
[144.9113739439796, -37.82618552508767, 0],
[144.9112740633105, -37.82615750100924, 0],
[144.9111355846674, -37.82584493693527, 0],
[144.9097088901841, -37.82622654171794, 0]
]
]
}
},
{
"type": "Feature",
"properties": {
"name": "George Weston Foods Limited",
"geo": [-37.05202791502396, 144.2085614999388],
"streetAddress": "67 Richards Road",
"addressLocality": "Castlemaine",
"addressRegion": "Victoria",
"addressCountry": "Australia",
"postalCode": "3450"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[144.2052428913937, -37.04906391287216, 0],
[144.205540392692, -37.05049727485623, 0],
[144.2059800881858, -37.05066835966983, 0],
[144.206490656024, -37.05279538900776, 0],
[144.2064525845008, -37.05366195881602, 0],
[144.2084322301922, -37.0538920493147, 0],
[144.2084811895712, -37.05266519735124, 0],
[144.2079784002005, -37.05041270555773, 0],
[144.2074017905817, -37.04817406993293, 0],
[144.2061363939852, -37.04834972871226, 0],
[144.2052428913937, -37.04906391287216, 0]
]
]
}
}
]
}

File diff suppressed because one or more lines are too long

23
samples/JSX/sample.jsx Normal file
View File

@@ -0,0 +1,23 @@
'use strict';
const React = require('react')
module.exports = React.createClass({
render: function() {
let {feeds, log} = this.props;
log.info(feeds);
return <div className="feed-list">
<h3>News Feed's</h3>
<ul>
{feeds.map(function(feed) {
return <li key={feed.name} className={feed.fetched ? 'loaded' : 'loading'}>
{feed.data && feed.data.length > 0 ?
<span>{feed.name} <span className='light'>({feed.data.length})</span></span>
: 'feed.name' }
</li>
})}
</ul>
</div>;
}
});

View File

@@ -0,0 +1,19 @@
// title : OpenJSCAD.org Logo
// author : Rene K. Mueller
// license : MIT License
// revision : 0.003
// tags : Logo,Intersection,Sphere,Cube
// file : logo.jscad
function main() {
return union(
difference(
cube({size: 3, center: true}),
sphere({r:2, center: true})
),
intersection(
sphere({r: 1.3, center: true}),
cube({size: 2.1, center: true})
)
).translate([0,0,1.5]).scale(10);
}

14069
samples/KiCad/tc14badge.brd Normal file

File diff suppressed because it is too large Load Diff

74
samples/LSL/LSL.lslp Normal file
View File

@@ -0,0 +1,74 @@
/*
Testing syntax highlighting
for the Linden Scripting Language
*/
integer someIntNormal = 3672;
integer someIntHex = 0x00000000;
integer someIntMath = PI_BY_TWO;
integer event = 5673;// 'event' is invalid.illegal
key someKeyTexture = TEXTURE_DEFAULT;
string someStringSpecial = EOF;
some_user_defined_function_without_return_type(string inputAsString)
{
llSay(PUBLIC_CHANNEL, inputAsString);
}
string user_defined_function_returning_a_string(key inputAsKey)
{
return (string)inputAsKey;
}
default
{
state_entry()
{
key someKey = NULL_KEY;
someKey = llGetOwner();
string someString = user_defined_function_returning_a_string(someKey);
some_user_defined_function_without_return_type(someString);
}
touch_start(integer num_detected)
{
list agentsInRegion = llGetAgentList(AGENT_LIST_REGION, []);
integer numOfAgents = llGetListLength(agentsInRegion);
integer index; // defaults to 0
for (; index <= numOfAgents - 1; index++) // for each agent in region
{
llRegionSayTo(llList2Key(agentsInRegion, index), PUBLIC_CHANNEL, "Hello, Avatar!");
}
}
touch_end(integer num_detected)
{
someIntNormal = 3672;
someIntHex = 0x00000000;
someIntMath = PI_BY_TWO;
event = 5673;// 'event' is invalid.illegal
someKeyTexture = TEXTURE_DEFAULT;
someStringSpecial = EOF;
llSetInventoryPermMask("some item", MASK_NEXT, PERM_ALL);// 'llSetInventoryPermMask' is reserved.godmode
llWhisper(PUBLIC_CHANNEL, "Leaving \"default\" now...");
state other;
}
}
state other
{
state_entry()
{
llWhisper(PUBLIC_CHANNEL, "Entered \"state other\", returning to \"default\" again...");
state default;
}
}

View File

@@ -0,0 +1,99 @@
// Copyright 2014 Isis Innovation Limited and the authors of InfiniTAM
#include <metal_stdlib>
#include "../../DeviceAgnostic/ITMSceneReconstructionEngine.h"
#include "../../DeviceAgnostic/ITMVisualisationEngine.h"
#include "ITMVisualisationEngine_Metal.h"
using namespace metal;
kernel void genericRaycastVH_device(DEVICEPTR(Vector4f) *pointsRay [[ buffer(0) ]],
const CONSTPTR(ITMVoxel) *voxelData [[ buffer(1) ]],
const CONSTPTR(typename ITMVoxelIndex::IndexData) *voxelIndex [[ buffer(2) ]],
const CONSTPTR(Vector2f) *minmaxdata [[ buffer(3) ]],
const CONSTPTR(CreateICPMaps_Params) *params [[ buffer(4) ]],
uint2 threadIdx [[ thread_position_in_threadgroup ]],
uint2 blockIdx [[ threadgroup_position_in_grid ]],
uint2 blockDim [[ threads_per_threadgroup ]])
{
int x = threadIdx.x + blockIdx.x * blockDim.x, y = threadIdx.y + blockIdx.y * blockDim.y;
if (x >= params->imgSize.x || y >= params->imgSize.y) return;
int locId = x + y * params->imgSize.x;
int locId2 = (int)floor((float)x / minmaximg_subsample) + (int)floor((float)y / minmaximg_subsample) * params->imgSize.x;
castRay<ITMVoxel, ITMVoxelIndex>(pointsRay[locId], x, y, voxelData, voxelIndex, params->invM, params->invProjParams,
params->voxelSizes.y, params->lightSource.w, minmaxdata[locId2]);
}
kernel void genericRaycastVGMissingPoints_device(DEVICEPTR(Vector4f) *forwardProjection [[ buffer(0) ]],
const CONSTPTR(int) *fwdProjMissingPoints [[ buffer(1) ]],
const CONSTPTR(ITMVoxel) *voxelData [[ buffer(2) ]],
const CONSTPTR(typename ITMVoxelIndex::IndexData) *voxelIndex [[ buffer(3) ]],
const CONSTPTR(Vector2f) *minmaxdata [[ buffer(4) ]],
const CONSTPTR(CreateICPMaps_Params) *params [[ buffer(5) ]],
uint2 threadIdx [[ thread_position_in_threadgroup ]],
uint2 blockIdx [[ threadgroup_position_in_grid ]],
uint2 blockDim [[ threads_per_threadgroup ]])
{
int pointId = threadIdx.x + blockIdx.x * blockDim.x;
if (pointId >= params->imgSize.z) return;
int locId = fwdProjMissingPoints[pointId];
int y = locId / params->imgSize.x, x = locId - y * params->imgSize.x;
int locId2 = (int)floor((float)x / minmaximg_subsample) + (int)floor((float)y / minmaximg_subsample) * params->imgSize.x;
castRay<ITMVoxel, ITMVoxelIndex>(forwardProjection[locId], x, y, voxelData, voxelIndex, params->invM, params->invProjParams,
params->voxelSizes.y, params->lightSource.w, minmaxdata[locId2]);
}
kernel void renderICP_device(const CONSTPTR(Vector4f) *pointsRay [[ buffer(0) ]],
DEVICEPTR(Vector4f) *pointsMap [[ buffer(1) ]],
DEVICEPTR(Vector4f) *normalsMap [[ buffer(2) ]],
DEVICEPTR(Vector4u) *outRendering [[ buffer(3) ]],
const CONSTPTR(CreateICPMaps_Params) *params [[ buffer(4) ]],
uint2 threadIdx [[ thread_position_in_threadgroup ]],
uint2 blockIdx [[ threadgroup_position_in_grid ]],
uint2 blockDim [[ threads_per_threadgroup ]])
{
int x = threadIdx.x + blockIdx.x * blockDim.x, y = threadIdx.y + blockIdx.y * blockDim.y;
if (x >= params->imgSize.x || y >= params->imgSize.y) return;
processPixelICP<false>(outRendering, pointsMap, normalsMap, pointsRay, params->imgSize.xy, x, y, params->voxelSizes.x, TO_VECTOR3(params->lightSource));
}
kernel void renderForward_device(DEVICEPTR(Vector4u) *outRendering [[ buffer(0) ]],
const CONSTPTR(Vector4f) *pointsRay [[ buffer(1) ]],
const CONSTPTR(CreateICPMaps_Params) *params [[ buffer(2) ]],
uint2 threadIdx [[ thread_position_in_threadgroup ]],
uint2 blockIdx [[ threadgroup_position_in_grid ]],
uint2 blockDim [[ threads_per_threadgroup ]])
{
int x = threadIdx.x + blockIdx.x * blockDim.x, y = threadIdx.y + blockIdx.y * blockDim.y;
if (x >= params->imgSize.x || y >= params->imgSize.y) return;
processPixelForwardRender<false>(outRendering, pointsRay, params->imgSize.xy, x, y, params->voxelSizes.x, TO_VECTOR3(params->lightSource));
}
kernel void forwardProject_device(DEVICEPTR(Vector4f) *forwardProjection [[ buffer(0) ]],
const CONSTPTR(Vector4f) *pointsRay [[ buffer(1) ]],
const CONSTPTR(CreateICPMaps_Params) *params [[ buffer(2) ]],
uint2 threadIdx [[ thread_position_in_threadgroup ]],
uint2 blockIdx [[ threadgroup_position_in_grid ]],
uint2 blockDim [[ threads_per_threadgroup ]])
{
int x = (threadIdx.x + blockIdx.x * blockDim.x), y = (threadIdx.y + blockIdx.y * blockDim.y);
if (x >= params->imgSize.x || y >= params->imgSize.y) return;
int locId = x + y * params->imgSize.x;
Vector4f pixel = pointsRay[locId];
int locId_new = forwardProjectPixel(pixel * params->voxelSizes.x, params->M, params->projParams, params->imgSize.xy);
if (locId_new >= 0) forwardProjection[locId_new] = pixel;
}

View File

@@ -0,0 +1,16 @@
//
// Siesta.h
// Siesta
//
// Created by Paul on 2015/6/14.
// Copyright © 2015 Bust Out Solutions. MIT license.
//
#import <UIKit/UIKit.h>
//! Project version number for Siesta.
FOUNDATION_EXPORT double SiestaVersionNumber;
//! Project version string for Siesta.
FOUNDATION_EXPORT const unsigned char SiestaVersionString[];

31
samples/PHP/mail.phps Normal file
View File

@@ -0,0 +1,31 @@
<?php
/**
* This example shows sending a message using PHP's mail() function.
*/
require '../PHPMailerAutoload.php';
//Create a new PHPMailer instance
$mail = new PHPMailer;
//Set who the message is to be sent from
$mail->setFrom('from@example.com', 'First Last');
//Set an alternative reply-to address
$mail->addReplyTo('replyto@example.com', 'First Last');
//Set who the message is to be sent to
$mail->addAddress('whoto@example.com', 'John Doe');
//Set the subject line
$mail->Subject = 'PHPMailer mail() test';
//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));
//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';
//Attach an image file
$mail->addAttachment('images/phpmailer_mini.png');
//send the message, check for errors
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}

View File

@@ -0,0 +1,90 @@
create or replace package plsqlguide is
-- Author : Jared Petersen
-- Created : 9/22/2015 12:26:22 AM
-- Purpose : Basic PLSQL template/guide
/* Procedures */
procedure p_main;
end plsqlguide;
/
create or replace package body plsqlguide is
/* Main entry point (homepage) */
procedure p_main
is
begin
htp.prn('
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>PL/SQL Sample Application</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<!-- Static navbar -->
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">PL/SQL Sample Application</a>
</div>
</div>
</nav>
<div class="container">
<table class="table table-bordered">
<tr>
<th>#</th>
<th>Name</th>
<th>Description</th>
<th>Quantity</th>
<th>Price</th>
</tr>
');
-- Fill out the parts table
for row in (select * from parts) loop
htp.prn('
<tr>
<td>'||row.pid||'</td>
<td>'||row.name||'</td>
<td>'||row.description||'</td>
<td>'||row.quantity||'</td>
<td>'||row.price||'</td>
</tr>
');
end loop;
htp.prn('
</table>
</div> <!-- /container -->
<!-- jQuery (necessary for Bootstrap''s JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
');
end p_main;
begin
-- Initialization
null;
end plsqlguide;
/

24
samples/Pickle/data.pkl Normal file
View File

@@ -0,0 +1,24 @@
(dp0
S'a'
p1
(lp2
I1
aF2.0
aI3
ac__builtin__
complex
p3
(F4.0
F6.0
tp4
Rp5
asS'c'
p6
NsS'b'
p7
(S'string'
p8
VUnicode string
p9
tp10
s.

File diff suppressed because one or more lines are too long

36
samples/Pickle/random.pkl Normal file
View File

@@ -0,0 +1,36 @@
cnumpy.core.multiarray
_reconstruct
p0
(cnumpy
ndarray
p1
(I0
tp2
S'b'
p3
tp4
Rp5
(I1
(I100
tp6
cnumpy
dtype
p7
(S'f8'
p8
I0
I1
tp9
Rp10
(I3
S'<'
p11
NNNI-1
I-1
I0
tp12
bI00
S'\x1cc~\xc3\xa7r\xed?\xe5${\xec\xd6\xcd\xed?\x809-\x02%\xa9\xa2?F\x0f\x1d\xe8\xef\xa3\xdb?\xfe\xd1\x0c\xb7\x83\x13\xef?\xe0<o\xa1\xa9^\xdf?CE\x96\x88/o\xe2?<\xd8\xa1\x96\xa2T\xce?\x152\x8e\xe5\xa8\x7f\xe8?\xe4\xb7\x9a\xe0$\x0f\xdc?\x90\xe4\xe2\xd4=\xce\xc3?Ix\xe3P\xc4C\xe1?\x16\xd17\xc1Y\xfc\xed?5\xd7\xae@4\xfa\xe8?\x0f\x87\x8d>\xfcO\xe5?Y\x97\xcb"\xa7%\xe7?\x9b\x8d\x16\xda\x97\xe1\xeb?T\x14\xbd\xfe|\xf4\xd0?\x18\xdfH\xc56A\xba?\x90\xc5\xfb\xc63:\xe5?\xbf%\xad\xe5.\x86\xe9?\xc6\x0c\xa9\x8c\xd7\xd5\xe9?\xf8\xafc:\x84g\xd7?\xf8\x98\x879\x9a\x16\xee?\xba\xdf\x88\x8az\x06\xe2?~g-\xeb\xc8\xed\xee?\x08A\xcc\x8c\xe7>\xef?\xceD\xc4ar\n\xdc?\x92w\xbb\xa34\xb1\xd9?\x88\xb9\xc0{u\xa3\xdc?d\x1a\xad\xe8\xf3\x14\xdd?\x9c\x95\x13\x96o?\xe5?\x9cT[\xb8r\xa9\xe5?0\xf1\x01+(\x0f\xdf?W\xbdjqD&\xed?c\xcf1-W\xe6\xe1?\xce\xbc\xe1{zW\xd9?"d\xcf\xd7\x13\x93\xde?\xf2P\xf6\xc3\xd6\x87\xd5?\xc2\x0e\x92q\x89\xda\xd5?\xc0:B\x1bb\x00\x9e?Y\xafHmr\x80\xe3?\x1co\xa7\xba\xa5/\xe4?\xa2\xbc \x9c\xddB\xd0?\xd2L\x935\x17\'\xee?|\x8cM\xeb\x97=\xe8?\x0f0xN*V\xea?\x81p\xe3,!\xf2\xee?\xf5w\xed\x10\x9eu\xe0?\xc5\x16\\LR\xb5\xe1?\xbeh\x04\xa4g\xe5\xd6?\xea\xc0\xb9\xf0\xb2\xd8\xd9?\xac\x9c\xeep\x1a\xa9\xd8?@W9hp\x16\xb1?\xc4\xedS\xd6V\xa1\xed?\x93,!\xdc\xa1\x8b\xe9?\x80)\xb1\xa6[T\xc9?\xac\xbc\x8a\xd21\xdd\xc5?\x80\x9c.g\xf1\xf2\xc6?\tLu\xc3\xf7U\xe9?n\'\x9f?\xbe\xf9\xe9?\xa3\xe7K\x1c\xb3\xa9\xea?X\x98\x1a\xcb\xa0\xcd\xd3? \xb6O\x9c\x1bQ\xc2?"\x89[\xad1\x8e\xea?\xdd\x8f\xa0P\xc7\x0e\xe2?c\xa4j\xa3\r\xac\xef?\xba\xb6\x0f\x8emo\xef?\xe0\xed\xa0\xc5R9\xab?U\xf1\xcd\xcf\xbf\xcb\xea?\x89*#\x06\xb0|\xe8?d\xa3\xad\xcd\xe0]\xcc?\xb5\xe78\xa7w\x13\xe3?\xce\x99\x98\xefS%\xd7?\xb1\xf8\xd8\x8eI\x13\xef?\x91`]\x93\xd4 \xec?\xc0\rPz\xee\xbd\xe7?7\x92\xd4\x0fP\x8f\xe1?L\x0f\xaf\xa9\xc3\x19\xdd?\\}\x15X\x870\xc7? ~ t\xcat\xb1?@?\xec\x97u\x05\xe9?F\x8d:\xac4D\xdb?qY\xe1Qk|\xe2? \xaf\xeaj\xa5\x04\xab?J[\x1al;\x00\xd5?\x00^{n\xc2\xf1S?\xb0\x82dN\xda\xb5\xc7?\xe0 \x07\xe1?R\x92?\xc4\r\x08+\x99J\xe1?I|&U\x19\xc4\xe1?|*\xf9\xebq\x7f\xed?\xbc*\x93\x89k\xab\xe9?oiL\x90;\xe0\xef?\x96\xcd\x9b\xff\x18g\xdc?pt\xb4\xa5\x9c\xa2\xbc?Nu]w*\xb7\xd2?\x88k\xac\xd0\xfd\xbf\xd5?Q\x02$b\xfeH\xea?5\xf6\t\xb6K\x1a\xee?'
p13
tp14
b.

10
samples/Pickle/save.pkl Normal file
View File

@@ -0,0 +1,10 @@
(dp0
S'lion'
p1
S'yellow'
p2
sS'kitty'
p3
S'red'
p4
s.

30
samples/Pony/circle.pony Normal file
View File

@@ -0,0 +1,30 @@
use "collections"
class Circle
var _radius: F32
new create(radius': F32) =>
_radius = radius'
fun ref get_radius(): F32 =>
_radius
fun ref get_area(): F32 =>
F32.pi() * _radius.pow(2)
fun ref get_circumference(): F32 =>
2 * _radius * F32.pi()
actor Main
new create(env: Env) =>
for i in Range[F32](1.0, 101.0) do
let c = Circle(i)
var str =
"Radius: " + c.get_radius().string() + "\n" +
"Circumference: " + c.get_circumference().string() + "\n" +
"Area: " + c.get_area().string() + "\n"
env.out.print(str)
end

32
samples/Pony/counter.pony Normal file
View File

@@ -0,0 +1,32 @@
use "collections"
actor Counter
var _count: U32
new create() =>
_count = 0
be increment() =>
_count = _count + 1
be get_and_reset(main: Main) =>
main.display(_count)
_count = 0
actor Main
var _env: Env
new create(env: Env) =>
_env = env
var count: U32 = try env.args(1).u32() else 10 end
var counter = Counter
for i in Range[U32](0, count) do
counter.increment()
end
counter.get_and_reset(this)
be display(result: U32) =>
_env.out.print(result.string())

261
samples/Pony/gups-opt.pony Normal file
View File

@@ -0,0 +1,261 @@
use "options"
use "time"
use "collections"
class Config
var logtable: U64 = 20
var iterate: U64 = 10000
var logchunk: U64 = 10
var logactors: U64 = 2
fun ref apply(env: Env): Bool =>
var options = Options(env)
options
.add("logtable", "l", I64Argument)
.add("iterate", "i", I64Argument)
.add("chunk", "c", I64Argument)
.add("actors", "a", I64Argument)
for option in options do
match option
| ("table", var arg: I64) => logtable = arg.u64()
| ("iterate", var arg: I64) => iterate = arg.u64()
| ("chunk", var arg: I64) => logchunk = arg.u64()
| ("actors", var arg: I64) => logactors = arg.u64()
| let err: ParseError =>
err.report(env.out)
env.out.print(
"""
gups_opt [OPTIONS]
--table N log2 of the total table size. Defaults to 20.
--iterate N number of iterations. Defaults to 10000.
--chunk N log2 of the chunk size. Defaults to 10.
--actors N log2 of the actor count. Defaults to 2.
"""
)
return false
end
end
env.out.print(
"logtable: " + logtable.string() +
"\niterate: " + iterate.string() +
"\nlogchunk: " + logchunk.string() +
"\nlogactors: " + logactors.string()
)
true
actor Main
let _env: Env
let _config: Config = Config
var _updates: U64 = 0
var _confirm: U64 = 0
let _start: U64
var _actors: Array[Updater] val
new create(env: Env) =>
_env = env
if _config(env) then
let actor_count = 1 << _config.logactors
let loglocal = _config.logtable - _config.logactors
let chunk_size = 1 << _config.logchunk
let chunk_iterate = chunk_size * _config.iterate
_updates = chunk_iterate * actor_count
_confirm = actor_count
var updaters = recover Array[Updater](actor_count) end
for i in Range[U64](0, actor_count) do
updaters.push(Updater(this, actor_count, i, loglocal, chunk_size,
chunk_iterate * i))
end
_actors = consume updaters
_start = Time.nanos()
for a in _actors.values() do
a.start(_actors, _config.iterate)
end
else
_start = 0
_actors = recover Array[Updater] end
end
be done() =>
if (_confirm = _confirm - 1) == 1 then
for a in _actors.values() do
a.done()
end
end
be confirm() =>
_confirm = _confirm + 1
if _confirm == _actors.size() then
let elapsed = (Time.nanos() - _start).f64()
let gups = _updates.f64() / elapsed
_env.out.print(
"Time: " + (elapsed / 1e9).string() +
"\nGUPS: " + gups.string()
)
end
actor Updater
let _main: Main
let _index: U64
let _updaters: U64
let _chunk: U64
let _mask: U64
let _loglocal: U64
let _output: Array[Array[U64] iso]
let _reuse: List[Array[U64] iso] = List[Array[U64] iso]
var _others: (Array[Updater] val | None) = None
var _table: Array[U64]
var _rand: U64
new create(main:Main, updaters: U64, index: U64, loglocal: U64, chunk: U64,
seed: U64)
=>
_main = main
_index = index
_updaters = updaters
_chunk = chunk
_mask = updaters - 1
_loglocal = loglocal
_rand = PolyRand.seed(seed)
_output = _output.create(updaters)
let size = 1 << loglocal
_table = Array[U64].undefined(size)
var offset = index * size
try
for i in Range[U64](0, size) do
_table(i) = i + offset
end
end
be start(others: Array[Updater] val, iterate: U64) =>
_others = others
iteration(iterate)
be apply(iterate: U64) =>
iteration(iterate)
fun ref iteration(iterate: U64) =>
let chk = _chunk
for i in Range(0, _updaters) do
_output.push(
try
_reuse.pop()
else
recover Array[U64](chk) end
end
)
end
for i in Range(0, _chunk) do
var datum = _rand = PolyRand(_rand)
var updater = (datum >> _loglocal) and _mask
try
if updater == _index then
_table(i) = _table(i) xor datum
else
_output(updater).push(datum)
end
end
end
try
let to = _others as Array[Updater] val
repeat
let data = _output.pop()
if data.size() > 0 then
to(_output.size()).receive(consume data)
else
_reuse.push(consume data)
end
until _output.size() == 0 end
end
if iterate > 1 then
apply(iterate - 1)
else
_main.done()
end
be receive(data: Array[U64] iso) =>
try
for i in Range(0, data.size()) do
let datum = data(i)
var j = (datum >> _loglocal) and _mask
_table(j) = _table(j) xor datum
end
data.clear()
_reuse.push(consume data)
end
be done() =>
_main.confirm()
primitive PolyRand
fun apply(prev: U64): U64 =>
(prev << 1) xor if prev.i64() < 0 then _poly() else 0 end
fun seed(from: U64): U64 =>
var n = from % _period()
if n == 0 then
return 1
end
var m2 = Array[U64].undefined(64)
var temp = U64(1)
try
for i in Range(0, 64) do
m2(i) = temp
temp = this(temp)
temp = this(temp)
end
end
var i: U64 = 64 - n.clz()
var r = U64(2)
try
while i > 0 do
temp = 0
for j in Range(0, 64) do
if ((r >> j) and 1) != 0 then
temp = temp xor m2(j)
end
end
r = temp
i = i - 1
if ((n >> i) and 1) != 0 then
r = this(r)
end
end
end
r
fun _poly(): U64 => 7
fun _period(): U64 => 1317624576693539401

View File

@@ -0,0 +1,3 @@
actor Main
new create(env: Env) =>
env.out.print("Hello, world.")

View File

@@ -0,0 +1,188 @@
use "files"
use "options"
use "collections"
actor Worker
new mandelbrot(main: Main, x: U64, y: U64, width: U64, iterations: U64,
limit: F32, real: Array[F32] val, imaginary: Array[F32] val)
=>
var view: Array[U8] iso =
recover
Array[U8]((y - x) * (width >> 3))
end
let group_r = Array[F32].undefined(8)
let group_i = Array[F32].undefined(8)
var row = x
try
while row < y do
let prefetch_i = imaginary(row)
var col: U64 = 0
while col < width do
var j: U64 = 0
while j < 8 do
group_r.update(j, real(col + j))
group_i.update(j, prefetch_i)
j = j + 1
end
var bitmap: U8 = 0xFF
var n = iterations
repeat
var mask: U8 = 0x80
var k: U64 = 0
while k < 8 do
let r = group_r(k)
let i = group_i(k)
group_r.update(k, ((r * r) - (i * i)) + real(col + k))
group_i.update(k, (2.0 * r * i) + prefetch_i)
if ((r * r) + (i * i)) > limit then
bitmap = bitmap and not mask
end
mask = mask >> 1
k = k + 1
end
until (bitmap == 0) or ((n = n - 1) == 1) end
view.push(bitmap)
col = col + 8
end
row = row + 1
end
main.draw(x * (width >> 3), consume view)
end
actor Main
var iterations: U64 = 50
var limit: F32 = 4.0
var chunks: U64 = 16
var width: U64 = 16000
var actors: U64 = 0
var header: U64 = 0
var real: Array[F32] val = recover Array[F32] end
var imaginary: Array[F32] val = recover Array[F32] end
var outfile: (File | None) = None
new create(env: Env) =>
try
arguments(env)
let length = width
let recip_width = 2.0 / width.f32()
var r = recover Array[F32](length) end
var i = recover Array[F32](length) end
for j in Range(0, width) do
r.push((recip_width * j.f32()) - 1.5)
i.push((recip_width * j.f32()) - 1.0)
end
real = consume r
imaginary = consume i
spawn_actors()
create_outfile()
end
be draw(offset: U64, pixels: Array[U8] val) =>
match outfile
| var out: File =>
out.seek_start(header + offset)
out.write(pixels)
if (actors = actors - 1) == 1 then
out.dispose()
end
end
fun ref create_outfile() =>
match outfile
| var f: File =>
f.print("P4\n " + width.string() + " " + width.string() + "\n")
header = f.size()
f.set_length((width * (width >> 3)) + header)
end
fun ref spawn_actors() =>
actors = ((width + (chunks - 1)) / chunks)
var rest = width % chunks
if rest == 0 then rest = chunks end
var x: U64 = 0
var y: U64 = 0
for i in Range(0, actors - 1) do
x = i * chunks
y = x + chunks
Worker.mandelbrot(this, x, y, width, iterations, limit, real, imaginary)
end
Worker.mandelbrot(this, y, y + rest, width, iterations, limit, real,
imaginary)
fun ref arguments(env: Env) ? =>
let options = Options(env)
options
.add("iterations", "i", I64Argument)
.add("limit", "l", F64Argument)
.add("chunks", "c", I64Argument)
.add("width", "w", I64Argument)
.add("output", "o", StringArgument)
for option in options do
match option
| ("iterations", var arg: I64) => iterations = arg.u64()
| ("limit", var arg: F64) => limit = arg.f32()
| ("chunks", var arg: I64) => chunks = arg.u64()
| ("width", var arg: I64) => width = arg.u64()
| ("output", var arg: String) =>
outfile = try File(FilePath(env.root, arg)) end
| let err: ParseError => err.report(env.out) ; usage(env) ; error
end
end
fun tag usage(env: Env) =>
env.out.print(
"""
mandelbrot [OPTIONS]
The binary output can be converted to a BMP with the following command
(ImageMagick Tools required):
convert <output> JPEG:<output>.jpg
Available options:
--iterations, -i Maximum amount of iterations to be done for each pixel.
Defaults to 50.
--limit, -l Square of the limit that pixels need to exceed in order
to escape from the Mandelbrot set.
Defaults to 4.0.
--chunks, -c Maximum line count of chunks the image should be
divided into for divide & conquer processing.
Defaults to 16.
--width, -w Lateral length of the resulting mandelbrot image.
Defaults to 16000.
--output, -o File to write the output to.
"""
)

130
samples/Pony/mixed.pony Normal file
View File

@@ -0,0 +1,130 @@
use "collections"
actor Worker
var _env: Env
new create(env: Env) =>
_env = env
var a: U64 = 86028157
var b: U64 = 329545133
var result = factorize(a*b)
var correct =
try
(result.size() == 2) and
(result(0) == 86028157) and
(result(1) == 329545133)
else
false
end
fun ref factorize(bigint: U64) : Array[U64] =>
var factors = Array[U64](2)
if bigint <= 3 then
factors.push(bigint)
else
var d: U64 = 2
var i: U64 = 0
var n = bigint
while d < n do
if (n % d) == 0 then
i = i + 1
factors.push(d)
n = n / d
else
d = if d == 2 then 3 else (d + 2) end
end
end
factors.push(d)
end
factors
actor Ring
var _env: Env
var _size: U32
var _pass: U32
var _repetitions: U32
var _next: Ring
new create(env: Env, size: U32, pass: U32, repetitions: U32) =>
_env = env
_size = size
_pass = pass
_repetitions = repetitions
_next = spawn_ring(_env, _size, _pass)
run()
new neighbor(env: Env, next: Ring) =>
_env = env
_next = next
_size = 0
_pass = 0
_repetitions = 0
be apply(i: U32) =>
if i > 0 then
_next(i - 1)
else
run()
end
fun ref run() =>
if _repetitions > 0 then
_repetitions = _repetitions - 1
_next(_pass * _size)
Worker(_env)
end
fun tag spawn_ring(env: Env, size: U32, pass': U32) : Ring =>
var next: Ring = this
for i in Range[U32](0, size) do
next = Ring.neighbor(env, next)
end
next
actor Main
var _size: U32 = 50
var _count: U32 = 20
var _pass: U32 = 10000
var _repetitions: U32 = 5
var _env: Env
new create(env: Env) =>
_env = env
try
arguments()
start_benchmark()
else
usage()
end
fun ref arguments() ? =>
_count = _env.args(1).u32()
_size = _env.args(2).u32()
_pass = _env.args(3).u32()
_repetitions = _env.args(4).u32()
fun ref start_benchmark() =>
for i in Range[U32](0, _count) do
Ring(_env, _size, _pass, _repetitions)
end
fun ref usage() =>
_env.out.print(
"""
mixed OPTIONS
N number of actors in each ring"
N number of rings"
N number of messages to pass around each ring"
N number of times to repeat"
"""
)

267
samples/Ruby/racc.rb Normal file
View File

@@ -0,0 +1,267 @@
#
# DO NOT MODIFY!!!!
# This file is automatically generated by Racc 1.4.7
# from Racc grammer file "".
#
require 'racc/parser.rb'
module RJSON
class Parser < Racc::Parser
require 'rjson/handler'
attr_reader :handler
def initialize tokenizer, handler = Handler.new
@tokenizer = tokenizer
@handler = handler
super()
end
def next_token
@tokenizer.next_token
end
def parse
do_parse
handler
end
##### State transition tables begin ###
racc_action_table = [
9, 33, 9, 11, 13, 16, 19, 22, 9, 7,
23, 1, 9, 11, 13, 16, 19, 29, 30, 7,
21, 1, 9, 11, 13, 16, 19, 31, nil, 7,
21, 1, 23, 7, nil, 1 ]
racc_action_check = [
6, 27, 33, 33, 33, 33, 33, 3, 31, 33,
6, 33, 29, 29, 29, 29, 29, 12, 22, 29,
12, 29, 2, 2, 2, 2, 2, 25, nil, 2,
2, 2, 25, 0, nil, 0 ]
racc_action_pointer = [
24, nil, 20, 7, nil, nil, -2, nil, nil, nil,
nil, nil, 10, nil, nil, nil, nil, nil, nil, nil,
nil, nil, 18, nil, nil, 20, nil, -7, nil, 10,
nil, 6, nil, 0, nil, nil, nil ]
racc_action_default = [
-27, -12, -21, -27, -1, -2, -27, -10, -15, -26,
-8, -22, -27, -23, -17, -16, -24, -20, -18, -25,
-19, -11, -27, -13, -3, -27, -6, -27, -9, -21,
37, -27, -4, -21, -14, -5, -7 ]
racc_goto_table = [
8, 26, 24, 27, 10, 3, 25, 5, 4, 12,
nil, nil, nil, nil, 28, nil, nil, nil, nil, nil,
nil, 32, nil, nil, nil, nil, 35, 34, 27, nil,
nil, 36 ]
racc_goto_check = [
9, 7, 5, 8, 11, 1, 6, 3, 2, 12,
nil, nil, nil, nil, 11, nil, nil, nil, nil, nil,
nil, 5, nil, nil, nil, nil, 7, 9, 8, nil,
nil, 9 ]
racc_goto_pointer = [
nil, 5, 8, 7, nil, -4, 0, -5, -3, -2,
nil, 2, 7, nil, nil ]
racc_goto_default = [
nil, nil, 14, 18, 6, nil, nil, nil, 20, nil,
2, nil, nil, 15, 17 ]
racc_reduce_table = [
0, 0, :racc_error,
1, 14, :_reduce_none,
1, 14, :_reduce_none,
2, 15, :_reduce_none,
3, 15, :_reduce_none,
3, 19, :_reduce_none,
1, 19, :_reduce_none,
3, 20, :_reduce_none,
2, 16, :_reduce_none,
3, 16, :_reduce_none,
1, 23, :_reduce_10,
1, 24, :_reduce_11,
1, 17, :_reduce_12,
1, 18, :_reduce_13,
3, 25, :_reduce_none,
1, 25, :_reduce_none,
1, 22, :_reduce_none,
1, 22, :_reduce_none,
1, 22, :_reduce_none,
1, 26, :_reduce_none,
1, 26, :_reduce_20,
0, 27, :_reduce_none,
1, 27, :_reduce_22,
1, 27, :_reduce_23,
1, 27, :_reduce_24,
1, 27, :_reduce_25,
1, 21, :_reduce_26 ]
racc_reduce_n = 27
racc_shift_n = 37
racc_token_table = {
false => 0,
:error => 1,
:STRING => 2,
:NUMBER => 3,
:TRUE => 4,
:FALSE => 5,
:NULL => 6,
"," => 7,
":" => 8,
"[" => 9,
"]" => 10,
"{" => 11,
"}" => 12 }
racc_nt_base = 13
racc_use_result_var = true
Racc_arg = [
racc_action_table,
racc_action_check,
racc_action_default,
racc_action_pointer,
racc_goto_table,
racc_goto_check,
racc_goto_default,
racc_goto_pointer,
racc_nt_base,
racc_reduce_table,
racc_token_table,
racc_shift_n,
racc_reduce_n,
racc_use_result_var ]
Racc_token_to_s_table = [
"$end",
"error",
"STRING",
"NUMBER",
"TRUE",
"FALSE",
"NULL",
"\",\"",
"\":\"",
"\"[\"",
"\"]\"",
"\"{\"",
"\"}\"",
"$start",
"document",
"object",
"array",
"start_object",
"end_object",
"pairs",
"pair",
"string",
"value",
"start_array",
"end_array",
"values",
"scalar",
"literal" ]
Racc_debug_parser = false
##### State transition tables end #####
# reduce 0 omitted
# reduce 1 omitted
# reduce 2 omitted
# reduce 3 omitted
# reduce 4 omitted
# reduce 5 omitted
# reduce 6 omitted
# reduce 7 omitted
# reduce 8 omitted
# reduce 9 omitted
def _reduce_10(val, _values, result)
@handler.start_array
result
end
def _reduce_11(val, _values, result)
@handler.end_array
result
end
def _reduce_12(val, _values, result)
@handler.start_object
result
end
def _reduce_13(val, _values, result)
@handler.end_object
result
end
# reduce 14 omitted
# reduce 15 omitted
# reduce 16 omitted
# reduce 17 omitted
# reduce 18 omitted
# reduce 19 omitted
def _reduce_20(val, _values, result)
@handler.scalar val[0]
result
end
# reduce 21 omitted
def _reduce_22(val, _values, result)
n = val[0]; result = n.count('.') > 0 ? n.to_f : n.to_i
result
end
def _reduce_23(val, _values, result)
result = true
result
end
def _reduce_24(val, _values, result)
result = false
result
end
def _reduce_25(val, _values, result)
result = nil
result
end
def _reduce_26(val, _values, result)
@handler.scalar val[0].gsub(/^"|"$/, '')
result
end
def _reduce_none(val, _values, result)
val[0]
end
end # class Parser
end # module RJSON

View File

@@ -0,0 +1,27 @@
//@jsx: preserve
//@module: amd
//@filename: react.d.ts
declare module JSX {
interface Element { }
interface IntrinsicElements {
}
interface ElementAttributesProperty {
props;
}
}
interface Props {
foo: string;
}
//@filename: file.tsx
export class MyComponent {
render() {
}
props: { foo: string; }
}
<MyComponent foo="bar" />; // ok
<MyComponent foo={0} />; // should be an error

72
samples/X10/ArraySum.x10 Normal file
View File

@@ -0,0 +1,72 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.io.Console;
/**
* A simple illustration of loop parallelization within a single place.
*/
public class ArraySum {
var sum:Long;
val data:Rail[Long];
public def this(n:Long) {
// Create a Rail with n elements (0..(n-1)), all initialized to 1.
data = new Rail[Long](n, 1);
sum = 0;
}
def sum(a:Rail[Long], start:Long, last:Long) {
var mySum: Long = 0;
for (i in start..(last-1)) {
mySum += a(i);
}
return mySum;
}
def sum(numThreads:Long) {
val mySize = data.size/numThreads;
finish for (p in 0..(numThreads-1)) async {
val mySum = sum(data, p*mySize, (p+1)*mySize);
// Multiple activities will simultaneously update
// this location -- so use an atomic operation.
atomic sum += mySum;
}
}
public static def main(args:Rail[String]) {
var size:Long = 5*1000*1000;
if (args.size >=1)
size = Long.parse(args(0));
Console.OUT.println("Initializing.");
val a = new ArraySum(size);
val P = [1,2,4];
//warmup loop
Console.OUT.println("Warming up.");
for (numThreads in P)
a.sum(numThreads);
for (numThreads in P) {
Console.OUT.println("Starting with " + numThreads + " threads.");
a.sum=0;
var time: long = - System.nanoTime();
a.sum(numThreads);
time += System.nanoTime();
Console.OUT.println("For p=" + numThreads
+ " result: " + a.sum
+ ((size==a.sum)? " ok" : " bad")
+ " (time=" + (time/(1000*1000)) + " ms)");
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.xrx.Runtime;
/**
* Demonstrate how to instantiate the X10 runtime as an executor service
* submit jobs to the runtime, wait jobs to complete and cancel all jobs
*
* Compile with: x10c -O -EXECUTOR_MODE=true Cancellation.x10
* Run with: X10_CANCELLABLE=true X10_NPLACES=4 x10 -DX10RT_IMPL=JavaSockets Cancellation
*/
class Cancellation {
static def job(id:Long, iterations:Long) = ()=>{
at (Place.places().next(here)) async {
for (i in 1..iterations) {
finish for (p in Place.places()) {
at (p) async Console.OUT.println(here+" says hello (job " + id + ", iteration " + i + ")");
}
Console.ERR.println();
System.sleep(200);
}
}
};
public static def main(args:Rail[String]):void {
val w1 = Runtime.submit(job(1, 5));
w1.await(); Console.ERR.println("Job 1 completed\n");
val w2 = Runtime.submit(job(2, 1000));
System.threadSleep(1000);
val c1 = Runtime.cancelAll();
try { w2.await(); } catch (e:Exception) { Console.ERR.println("Job 2 aborted with exception " + e +"\n"); }
c1.await(); // waiting for cancellation to be processed
System.threadSleep(1000);
Runtime.submit(job(3, 1000));
Runtime.submit(job(4, 1000));
System.threadSleep(1000);
val c2 = Runtime.cancelAll();
c2.await();
Console.ERR.println("Goodbye\n");
}
}

52
samples/X10/Fibonacci.x10 Normal file
View File

@@ -0,0 +1,52 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.io.Console;
/**
* This is a small program to illustrate the use of
* <code>async</code> and <code>finish</code> in a
* prototypical recursive divide-and-conquer algorithm.
* It is obviously not intended to show a efficient way to
* compute Fibonacci numbers in X10.<p>
*
* The heart of the example is the <code>run</code> method,
* which directly embodies the recursive definition of
* <pre>
* fib(n) = fib(n-1)+fib(n-2);
* </pre>
* by using an <code>async</code> to compute <code>fib(n-1)</code> while
* the current activity computes <code>fib(n-2)</code>. A <code>finish</code>
* is used to ensure that both computations are complete before
* their results are added together to compute <code>fib(n)</code>
*/
public class Fibonacci {
public static def fib(n:long) {
if (n<=2) return 1;
val f1:long;
val f2:long;
finish {
async { f1 = fib(n-1); }
f2 = fib(n-2);
}
return f1 + f2;
}
public static def main(args:Rail[String]) {
val n = (args.size > 0) ? Long.parse(args(0)) : 10;
Console.OUT.println("Computing fib("+n+")");
val f = fib(n);
Console.OUT.println("fib("+n+") = "+f);
}
}

View File

@@ -0,0 +1,86 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.array.*;
import x10.compiler.Foreach;
import x10.compiler.Inline;
/**
* This is a sample program illustrating how to use
* X10's array classes. It also illustrates the use
* of foreach to acheive intra-place parallelism.
*
* The program solves a set of 2D partial differential
* equations by iteratively applying a 5-point stencil
* operation until convergence is reached.
*/
public class HeatTransfer_v0 {
static val EPSILON = 1.0e-5;
val N:Long;
val A:Array_2[Double]{self!=null};
val Tmp:Array_2[Double]{self!=null};
public def this(size:Long) {
N = size;
A = new Array_2[Double](N+2, N+2); // zero-initialized N+2 * N+2 array of doubles
for (j in 1..N) A(0, j) = 1; // set one border row to 1
Tmp = new Array_2[Double](A);
}
final @Inline def stencil(x:Long, y:Long):Double {
return (A(x-1,y) + A(x+1,y) + A(x,y-1) + A(x,y+1)) / 4;
}
def run() {
val is = new DenseIterationSpace_2(1,1,N,N);
var delta:Double;
do {
// Compute new values, storing in tmp
delta = Foreach.blockReduce(is,
(i:Long, j:Long)=>{
Tmp(i,j) = stencil(i,j);
// Reduce max element-wise delta (A now holds previous values)
return Math.abs(Tmp(i,j) - A(i,j));
},
(a:Double, b:Double)=>Math.max(a,b), 0.0
);
// swap backing data of A and Tmp
Array.swap(A, Tmp);
} while (delta > EPSILON);
}
def prettyPrintResult() {
for (i in 1..N) {
for (j in 1..N) {
Console.OUT.printf("%1.4f ",A(i,j));
}
Console.OUT.println();
}
}
public static def main(args:Rail[String]) {
val n = args.size > 0 ? Long.parse(args(0)) : 8;
Console.OUT.println("HeatTransfer example with N="+n+" and epsilon="+EPSILON);
Console.OUT.println("Initializing data structures");
val ht = new HeatTransfer_v0(n);
Console.OUT.println("Beginning computation...");
val start = System.nanoTime();
ht.run();
val stop = System.nanoTime();
Console.OUT.printf("...completed in %1.3f seconds.\n", ((stop-start) as double)/1e9);
if (n <= 10) {
ht.prettyPrintResult();
}
}
}

View File

@@ -0,0 +1,114 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.array.*;
import x10.compiler.Foreach;
import x10.util.Team;
/**
* This is a sample program illustrating how to use
* X10's distributed array classes. It also illustrates the use
* of foreach to achieve intra-place parallelism and the mixture
* of APGAS finish/async/at with Team collective operations.
*
* This version of the program uses a vanilla DistArray without
* ghost regions. As a result, the stencil function does
* inefficient fine-grained neighbor communication to get individual values.
* Compare this to HeatTransfer_v2 which utilizes ghost regions and
* bulk ghost-region exchange functions.
*
* The program solves a set of 2D partial differential
* equations by iteratively applying a 5-point stencil
* operation until convergence is reached.
*/
public class HeatTransfer_v1 {
static val EPSILON = 1.0e-5;
val N:Long;
val A:DistArray_BlockBlock_2[Double]{self!=null};
val Tmp:DistArray_BlockBlock_2[Double]{self!=null};
public def this(size:Long) {
N = size;
val init = (i:Long, j:Long)=>i==0 ? 1.0 : 0.0;
A = new DistArray_BlockBlock_2[Double](N+2, N+2, init);
Tmp = new DistArray_BlockBlock_2[Double](N+2, N+2, init);
}
final def stencil(x:Long, y:Long):Double {
val cls = (dx:Long, dy:Long)=>{
val p = A.place(x+dx, y+dy);
p == here ? A(x+dx,y+dy) : at (p) A(x+dx,y+dy)
};
val tmp = cls(-1,0) + cls(1,0) + cls(0,-1) + cls(0,1);
return tmp / 4;
}
def run() {
val myTeam = new Team(A.placeGroup());
finish for (p in A.placeGroup()) at (p) async {
// Compute the subset of the local indices on which
// we want to apply the stencil (the interior points of the N+2 x N+2 grid)
val li = A.localIndices();
val interior = new DenseIterationSpace_2(li.min(0) == 0 ? 1 : li.min(0),
li.min(1) == 0 ? 1 : li.min(1),
li.max(0) == N+1 ? N : li.max(0),
li.max(1) == N+1 ? N : li.max(1));
var delta:Double;
do {
// Compute new values, storing in tmp
val myDelta = Foreach.blockReduce(interior,
(i:Long, j:Long)=>{
Tmp(i,j) = stencil(i,j);
// Reduce max element-wise delta (A now holds previous values)
return Math.abs(Tmp(i,j) - A(i,j));
},
(a:Double, b:Double)=>Math.max(a,b), 0.0
);
myTeam.barrier();
// Unlike Array, DistArray doesn't provide an optimized swap.
// So, until it does, we have to copy the data elements.
Foreach.block(interior, (i:Long, j:Long)=>{
A(i,j) = Tmp(i,j);
});
delta = myTeam.allreduce(myDelta, Team.MAX);
} while (delta > EPSILON);
}
}
def prettyPrintResult() {
for (i in 1..N) {
for (j in 1..N) {
val x = at (A.place(i,j)) A(i,j);
Console.OUT.printf("%1.4f ", x);
}
Console.OUT.println();
}
}
public static def main(args:Rail[String]) {
val n = args.size > 0 ? Long.parse(args(0)) : 8;
Console.OUT.println("HeatTransfer example with N="+n+" and epsilon="+EPSILON);
Console.OUT.println("Initializing data structures");
val ht = new HeatTransfer_v1(n);
Console.OUT.println("Beginning computation...");
val start = System.nanoTime();
ht.run();
val stop = System.nanoTime();
Console.OUT.printf("...completed in %1.3f seconds.\n", ((stop-start) as double)/1e9);
if (n <= 10) {
ht.prettyPrintResult();
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.io.Console;
/**
* The classic hello world program, with a twist - prints a message
* from the command line at every Place.
* The messages from each Place may appear in any order, but the
* finish ensures that the last message printed will be "Goodbye"
* <pre>
* Typical output:
* [dgrove@linchen samples]$ ./HelloWholeWorld 'best wishes'
* Place(1) says hello and best wishes
* Place(2) says hello and best wishes
* Place(3) says hello and best wishes
* Place(0) says hello and best wishes
* Goodbye
* [dgrove@linchen samples]$
* </pre>
*/
class HelloWholeWorld {
public static def main(args:Rail[String]):void {
if (args.size < 1) {
Console.OUT.println("Usage: HelloWholeWorld message");
return;
}
finish for (p in Place.places()) {
at (p) async Console.OUT.println(here+" says hello and "+args(0));
}
Console.OUT.println("Goodbye");
}
}

View File

@@ -0,0 +1,23 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.io.Console;
/**
* The classic hello world program, shows how to output to the console.
*/
class HelloWorld {
public static def main(Rail[String]) {
Console.OUT.println("Hello World!" );
}
}

45
samples/X10/Histogram.x10 Normal file
View File

@@ -0,0 +1,45 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
public class Histogram {
public static def compute(data:Rail[Int], numBins:Int) {
val bins = new Rail[Int](numBins);
finish for (i in data.range) async {
val b = data(i) % numBins;
atomic bins(b)++;
}
return bins;
}
public static def run(N:Int, S:Int):Boolean {
val a = new Rail[Int](N, (i:long)=> i as int);
val b = compute(a, S);
val v = b(0);
var ok:Boolean = true;
for (x in b.range) ok &= (b(x)==v);
return ok;
}
public static def main(args:Rail[String]) {
if (args.size != 2L) {
Console.OUT.println("Usage: Histogram SizeOfArray NumberOfBins");
return;
}
val N = Int.parse(args(0));
val S = Int.parse(args(1));
val ok = run(N,S);
if (ok) {
Console.OUT.println("Test ok.");
} else {
Console.OUT.println("Test failed.");
}
}
}

55
samples/X10/Integrate.x10 Normal file
View File

@@ -0,0 +1,55 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
/**
* This is a slightly more realistic example of the
* basic computational pattern of using async/finish
* to express recursive divide-and-conquer algorithms.
* The program does integration via Guassian Quadrature.
* <p>
* It also can serve as an example of using a closure.
*/
public class Integrate {
static val epsilon = 1.0e-9;
val fun:(double)=>double;
public def this(f:(double)=>double) { fun = f; }
public def computeArea(left:double, right:double) {
return recEval(left, fun(left), right, fun(right), 0);
}
private def recEval(l:double, fl:double, r:double, fr:double, a:double) {
val h = (r - l) / 2;
val hh = h / 2;
val c = l + h;
val fc = fun(c);
val al = (fl + fc) * hh;
val ar = (fr + fc) * hh;
val alr = al + ar;
if (Math.abs(alr - a) < epsilon) return alr;
val expr1:double;
val expr2:double;
finish {
async { expr1 = recEval(c, fc, r, fr, ar); };
expr2 = recEval(l, fl, c, fc, al);
}
return expr1 + expr2;
}
public static def main(args:Rail[String]) {
val obj = new Integrate((x:double)=>(x*x + 1.0) * x);
val xMax = args.size > 0 ? Long.parse(args(0)) : 10;
val area = obj.computeArea(0, xMax);
Console.OUT.println("The area of (x*x +1) * x from 0 to "+xMax+" is "+area);
}
}

151
samples/X10/KMeans.x10 Normal file
View File

@@ -0,0 +1,151 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.io.Console;
import x10.util.Random;
/**
* A KMeans object o can compute K means of a given set of
* points of dimension o.myDim.
* <p>
* This class implements a sequential program, that is readily parallelizable.
*
* For a scalable, high-performance version of this benchmark see
* KMeans.x10 in the X10 Benchmarks (separate download from x10-lang.org)
*/
public class KMeans(myDim:Long) {
static val DIM=2;
static val K=4;
static val POINTS=2000;
static val ITERATIONS=50;
static val EPS=0.01F;
static type ValVector(k:Long) = Rail[Float]{self.size==k};
static type ValVector = ValVector(DIM);
static type Vector(k:Long) = Rail[Float]{self.size==k};
static type Vector = Vector(DIM);
static type SumVector(d:Long) = V{self.dim==d};
static type SumVector = SumVector(DIM);
/**
* V represents the sum of 'count' number of vectors of dimension 'dim'.
*/
static class V(dim:Long) implements (Long)=>Float {
var vec: Vector(dim);
var count:Int;
def this(dim:Long, init:(Long)=>Float): SumVector(dim) {
property(dim);
vec = new Rail[Float](this.dim, init);
count = 0n;
}
public operator this(i:Long) = vec(i);
def makeZero() {
for (i in 0..(dim-1))
vec(i) =0.0F;
count=0n;
}
def addIn(a:ValVector(dim)) {
for (i in 0..(dim-1))
vec(i) += a(i);
count++;
}
def div(f:Int) {
for (i in 0..(dim-1))
vec(i) /= f;
}
def dist(a:ValVector(dim)):Float {
var dist:Float=0.0F;
for (i in 0..(dim-1)) {
val tmp = vec(i)-a(i);
dist += tmp*tmp;
}
return dist;
}
def dist(a:SumVector(dim)):Float {
var dist:Float=0.0F;
for (i in 0..(dim-1)) {
val tmp = vec(i)-a(i);
dist += tmp*tmp;
}
return dist;
}
def print() {
Console.OUT.println();
for (i in 0..(dim-1)) {
Console.OUT.print((i>0? " " : "") + vec(i));
}
}
def normalize() { div(count);}
def count() = count;
}
def this(myDim:Long):KMeans{self.myDim==myDim} {
property(myDim);
}
static type KMeansData(myK:Long, myDim:Long)= Rail[SumVector(myDim)]{self.size==myK};
/**
* Compute myK means for the given set of points of dimension myDim.
*/
def computeMeans(myK:Long, points:Rail[ValVector(myDim)]):KMeansData(myK, myDim) {
var redCluster : KMeansData(myK, myDim) =
new Rail[SumVector(myDim)](myK, (i:long)=> new V(myDim, (j:long)=>points(i)(j)));
var blackCluster: KMeansData(myK, myDim) =
new Rail[SumVector(myDim)](myK, (i:long)=> new V(myDim, (j:long)=>0.0F));
for (i in 1..ITERATIONS) {
val tmp = redCluster;
redCluster = blackCluster;
blackCluster=tmp;
for (p in 0..(POINTS-1)) {
var closest:Long = -1;
var closestDist:Float = Float.MAX_VALUE;
val point = points(p);
for (k in 0..(myK-1)) { // compute closest mean in cluster.
val dist = blackCluster(k).dist(point);
if (dist < closestDist) {
closestDist = dist;
closest = k;
}
}
redCluster(closest).addIn(point);
}
for (k in 0..(myK-1))
redCluster(k).normalize();
var b:Boolean = true;
for (k in 0..(myK-1)) {
if (redCluster(k).dist(blackCluster(k)) > EPS) {
b=false;
break;
}
}
if (b)
break;
for (k in 0..(myK-1))
blackCluster(k).makeZero();
}
return redCluster;
}
public static def main (Rail[String]) {
val rnd = new Random(0);
val points = new Rail[ValVector](POINTS,
(long)=>new Rail[Float](DIM, (long)=>rnd.nextFloat()));
val result = new KMeans(DIM).computeMeans(K, points);
for (k in 0..(K-1)) result(k).print();
}
}
// vim: shiftwidth=4:tabstop=4:expandtab

147
samples/X10/KMeansDist.x10 Normal file
View File

@@ -0,0 +1,147 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.array.*;
import x10.io.Console;
import x10.util.Random;
/**
* A low performance formulation of distributed KMeans using fine-grained asyncs.
*
* For a highly optimized and scalable, version of this benchmark see
* KMeans.x10 in the X10 Benchmarks (separate download from x10-lang.org)
*/
public class KMeansDist {
static val DIM=2;
static val CLUSTERS=4;
static val POINTS=2000;
static val ITERATIONS=50;
public static def main (Rail[String]) {
val world = Place.places();
val local_curr_clusters =
PlaceLocalHandle.make[Array_2[Float]](world, () => new Array_2[Float](CLUSTERS, DIM));
val local_new_clusters =
PlaceLocalHandle.make[Array_2[Float]](world, () => new Array_2[Float](CLUSTERS, DIM));
val local_cluster_counts =
PlaceLocalHandle.make[Rail[Int]](world, ()=> new Rail[Int](CLUSTERS));
val rnd = PlaceLocalHandle.make[Random](world, () => new Random(0));
val points = new DistArray_Block_2[Float](POINTS, DIM, world, (Long,Long)=>rnd().nextFloat());
val central_clusters = new Array_2[Float](CLUSTERS, DIM, (i:Long, j:Long) => {
at (points.place(i,j)) points(i,j)
});
val old_central_clusters = new Array_2[Float](CLUSTERS, DIM);
val central_cluster_counts = new Rail[Int](CLUSTERS);
for (iter in 1..ITERATIONS) {
Console.OUT.println("Iteration: "+iter);
finish {
// reset state
for (d in world) at (d) async {
for ([i,j] in central_clusters.indices()) {
local_curr_clusters()(i, j) = central_clusters(i, j);
local_new_clusters()(i, j) = 0f;
}
local_cluster_counts().clear();
}
}
finish {
// compute new clusters and counters
for (p in 0..(POINTS-1)) {
at (points.place(p,0)) async {
var closest:Long = -1;
var closest_dist:Float = Float.MAX_VALUE;
for (k in 0..(CLUSTERS-1)) {
var dist : Float = 0;
for (d in 0..(DIM-1)) {
val tmp = points(p,d) - local_curr_clusters()(k, d);
dist += tmp * tmp;
}
if (dist < closest_dist) {
closest_dist = dist;
closest = k;
}
}
atomic {
for (d in 0..(DIM-1)) {
local_new_clusters()(closest,d) += points(p,d);
}
local_cluster_counts()(closest)++;
}
}
}
}
for ([i,j] in old_central_clusters.indices()) {
old_central_clusters(i, j) = central_clusters(i, j);
central_clusters(i, j) = 0f;
}
central_cluster_counts.clear();
finish {
val central_clusters_gr = GlobalRef(central_clusters);
val central_cluster_counts_gr = GlobalRef(central_cluster_counts);
val there = here;
for (d in world) at (d) async {
// access PlaceLocalHandles 'here' and then data will be captured by at and transfered to 'there' for accumulation
val tmp_new_clusters = local_new_clusters();
val tmp_cluster_counts = local_cluster_counts();
at (there) atomic {
for ([i,j] in tmp_new_clusters.indices()) {
central_clusters_gr()(i,j) += tmp_new_clusters(i,j);
}
for (j in 0..(CLUSTERS-1)) {
central_cluster_counts_gr()(j) += tmp_cluster_counts(j);
}
}
}
}
for (k in 0..(CLUSTERS-1)) {
for (d in 0..(DIM-1)) {
central_clusters(k, d) /= central_cluster_counts(k);
}
}
// TEST FOR CONVERGENCE
var b:Boolean = true;
for ([i,j] in old_central_clusters.indices()) {
if (Math.abs(old_central_clusters(i, j)-central_clusters(i, j))>0.0001) {
b = false;
break;
}
}
if (b) break;
}
for (d in 0..(DIM-1)) {
for (k in 0..(CLUSTERS-1)) {
if (k>0)
Console.OUT.print(" ");
Console.OUT.print(central_clusters(k,d));
}
Console.OUT.println();
}
}
}
// vim: shiftwidth=4:tabstop=4:expandtab

View File

@@ -0,0 +1,144 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2015.
*/
import x10.array.Array;
import x10.array.Array_2;
import x10.compiler.Foreach;
import x10.util.Random;
/**
* A better formulation of distributed KMeans using coarse-grained asyncs to
* implement an allreduce pattern for cluster centers and counts.
*
* For a highly optimized and scalable, version of this benchmark see
* KMeans.x10 in the X10 Benchmarks (separate download from x10-lang.org)
*/
public class KMeansDistPlh {
static val DIM=2;
static val CLUSTERS=4;
static class ClusterState {
val clusters = new Array_2[Float](CLUSTERS, DIM);
val clusterCounts = new Rail[Int](CLUSTERS);
}
public static def main(args:Rail[String]) {
val numPoints = args.size > 0 ? Long.parse(args(0)) : 2000;
val iterations = args.size > 1 ? Long.parse(args(1)) : 50;
val world = Place.places();
val clusterStatePlh = PlaceLocalHandle.make[ClusterState](world, () => new ClusterState());
val currentClustersPlh = PlaceLocalHandle.make[Array_2[Float]](world, () => new Array_2[Float](CLUSTERS, DIM));
val pointsPlh = PlaceLocalHandle.make[Array_2[Float]](world, () => {
val rand = new Random(here.id);
return new Array_2[Float](numPoints/world.size(), DIM, (Long,Long)=>rand.nextFloat());
});
val centralCurrentClusters = new Array_2[Float](CLUSTERS, DIM);
val centralNewClusters = new Array_2[Float](CLUSTERS, DIM);
val centralClusterCounts = new Rail[Int](CLUSTERS);
// arbitrarily initialize central clusters to first few points
for ([i,j] in centralCurrentClusters.indices()) {
centralCurrentClusters(i,j) = pointsPlh()(i,j);
}
for (iter in 1..iterations) {
Console.OUT.println("Iteration: "+iter);
finish {
for (place in world) async {
val placeClusters = at(place) {
val currentClusters = currentClustersPlh();
Array.copy(centralCurrentClusters, currentClusters);
val clusterState = clusterStatePlh();
val newClusters = clusterState.clusters;
newClusters.clear();
val clusterCounts = clusterState.clusterCounts;
clusterCounts.clear();
// compute new clusters and counters
val points = pointsPlh();
for (p in 0..(points.numElems_1-1)) {
var closest:Long = -1;
var closestDist:Float = Float.MAX_VALUE;
for (k in 0..(CLUSTERS-1)) {
var dist : Float = 0;
for (d in 0..(DIM-1)) {
val tmp = points(p,d) - currentClusters(k, d);
dist += tmp * tmp;
}
if (dist < closestDist) {
closestDist = dist;
closest = k;
}
}
atomic {
for (d in 0..(DIM-1)) {
newClusters(closest,d) += points(p,d);
}
clusterCounts(closest)++;
}
}
clusterState
};
// combine place clusters to central
atomic {
for ([i,j] in centralNewClusters.indices()) {
centralNewClusters(i,j) += placeClusters.clusters(i,j);
}
for (j in 0..(CLUSTERS-1)) {
centralClusterCounts(j) += placeClusters.clusterCounts(j);
}
}
}
}
for (k in 0..(CLUSTERS-1)) {
for (d in 0..(DIM-1)) {
centralNewClusters(k, d) /= centralClusterCounts(k);
}
}
// TEST FOR CONVERGENCE
var b:Boolean = true;
for ([i,j] in centralCurrentClusters.indices()) {
if (Math.abs(centralCurrentClusters(i, j)-centralNewClusters(i, j)) > 0.0001) {
b = false;
break;
}
}
Array.copy(centralNewClusters, centralCurrentClusters);
if (b) break;
centralNewClusters.clear();
centralClusterCounts.clear();
}
for (d in 0..(DIM-1)) {
for (k in 0..(CLUSTERS-1)) {
if (k > 0)
Console.OUT.print(" ");
Console.OUT.print(centralCurrentClusters(k,d));
}
Console.OUT.println();
}
}
}
// vim: shiftwidth=4:tabstop=4:expandtab

192
samples/X10/KMeansSPMD.x10 Normal file
View File

@@ -0,0 +1,192 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.io.Console;
import x10.io.File;
import x10.io.Marshal;
import x10.io.IOException;
import x10.util.OptionsParser;
import x10.util.Option;
import x10.util.Team;
/**
* An SPMD formulation of KMeans.
*
* For a highly optimized and scalable version of this benchmark see
* KMeans.x10 in the X10 Benchmarks (separate download from x10-lang.org)
*/
public class KMeansSPMD {
public static def printClusters (clusters:Rail[Float], dims:long) {
for (d in 0..(dims-1)) {
for (k in 0..(clusters.size/dims-1)) {
if (k>0)
Console.OUT.print(" ");
Console.OUT.print(clusters(k*dims+d).toString());
}
Console.OUT.println();
}
}
public static def main (args:Rail[String]) {here == Place.FIRST_PLACE } {
val opts = new OptionsParser(args, [
Option("q","quiet","just print time taken"),
Option("v","verbose","print out each iteration"),
Option("h","help","this information")
], [
Option("p","points","location of data file"),
Option("i","iterations","quit after this many iterations"),
Option("c","clusters","number of clusters to find"),
Option("d","dim","number of dimensions"),
Option("s","slices","factor by which to oversubscribe computational resources"),
Option("n","num","quantity of points")
]);
if (opts.filteredArgs().size!=0L) {
Console.ERR.println("Unexpected arguments: "+opts.filteredArgs());
Console.ERR.println("Use -h or --help.");
System.setExitCode(1n);
return;
}
if (opts("-h")) {
Console.OUT.println(opts.usage(""));
return;
}
val fname = opts("-p", "points.dat");
val num_clusters=opts("-c",4);
val num_slices=opts("-s",1);
val num_global_points=opts("-n", 2000);
val iterations=opts("-i",50);
val dim=opts("-d", 4);
val verbose = opts("-v");
val quiet = opts("-q");
if (!quiet)
Console.OUT.println("points: "+num_global_points+" clusters: "+num_clusters+" dim: "+dim);
// file is dimension-major
val file = new File(fname);
val fr = file.openRead();
val init_points = (long) => Float.fromIntBits(Marshal.INT.read(fr).reverseBytes());
val num_file_points = (file.size() / dim / 4) as Int;
val file_points = new Rail[Float](num_file_points*dim, init_points);
val team = Team.WORLD;
val num_slice_points = num_global_points / num_slices / Place.numPlaces();
finish {
for (h in Place.places()) at(h) async {
var compute_time:Long = 0;
var comm_time:Long = 0;
var barrier_time:Long = 0;
val host_clusters = new Rail[Float](num_clusters*dim, (i:long)=>file_points(i));
val host_cluster_counts = new Rail[Int](num_clusters);
for (slice in 0..(num_slices-1)) {
// carve out local portion of points (point-major)
val offset = (slice*Place.numPlaces() + here.id) * num_slice_points;
if (verbose)
Console.OUT.println(h.toString()+" gets "+offset+" len "+num_slice_points);
val init = (i:long) => {
val p=i%num_slice_points;
val d=i/num_slice_points;
return file_points(offset+p+d*num_file_points);
};
// these are pretty big so allocate up front
val host_points = new Rail[Float](num_slice_points*dim, init);
val host_nearest = new Rail[Float](num_slice_points);
val start_time = System.currentTimeMillis();
barrier_time -= System.nanoTime();
team.barrier();
barrier_time += System.nanoTime();
main_loop: for (iter in 0..(iterations-1)) {
//if (offset==0) Console.OUT.println("Iteration: "+iter);
val old_clusters = new Rail[Float](host_clusters.size);
Rail.copy(host_clusters, 0L, old_clusters, 0L, host_clusters.size);
host_clusters.clear();
host_cluster_counts.clear();
compute_time -= System.nanoTime();
for (p in 0..(num_slice_points-1)) {
var closest:Long = -1;
var closest_dist:Float = Float.MAX_VALUE;
for (k in 0..(num_clusters-1)) {
var dist : Float = 0;
for (d in 0..(dim-1)) {
val tmp = host_points(p+d*num_slice_points) - old_clusters(k*dim+d);
dist += tmp * tmp;
}
if (dist < closest_dist) {
closest_dist = dist;
closest = k;
}
}
for (d in 0..(dim-1)) {
host_clusters(closest*dim+d) += host_points(p+d*num_slice_points);
}
host_cluster_counts(closest)++;
}
compute_time += System.nanoTime();
comm_time -= System.nanoTime();
team.allreduce(host_clusters, 0L, host_clusters, 0L, host_clusters.size, Team.ADD);
team.allreduce(host_cluster_counts, 0L, host_cluster_counts, 0L, host_cluster_counts.size, Team.ADD);
comm_time += System.nanoTime();
for (k in 0..(num_clusters-1)) {
for (d in 0..(dim-1)) host_clusters(k*dim+d) /= host_cluster_counts(k);
}
if (offset==0 && verbose) {
Console.OUT.println("Iteration: "+iter);
printClusters(host_clusters,dim);
}
// TEST FOR CONVERGENCE
for (j in 0..(num_clusters*dim-1)) {
if (true/*||Math.abs(clusters_old(j)-host_clusters(j))>0.0001*/) continue main_loop;
}
break;
} // main_loop
} // slice
Console.OUT.printf("%d: computation %.3f s communication %.3f s (barrier %.3f s)\n",
here.id, compute_time/1E9, comm_time/1E9, barrier_time/1E9);
team.barrier();
if (here.id == 0) {
Console.OUT.println("\nFinal results:");
printClusters(host_clusters,dim);
}
} // async
} // finish
}
}
// vim: shiftwidth=4:tabstop=4:expandtab

42
samples/X10/MontyPi.x10 Normal file
View File

@@ -0,0 +1,42 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.array.DistArray_Unique;
import x10.io.Console;
import x10.util.Random;
/**
* Calculation of an approximation to pi by using a Monte Carlo simulation
* (throwing darts into the unit square and determining the fraction that land
* in the unit circle).
*/
public class MontyPi {
public static def main(args:Rail[String]) {
if (args.size != 1L) {
Console.OUT.println("Usage: MontyPi <number of points>");
return;
}
val N = Long.parse(args(0));
val initializer = () => {
val r = new Random();
var result:Long = 0;
for(c in 1..N) {
val x = r.nextDouble();
val y = r.nextDouble();
if (x*x +y*y <= 1.0) result++;
}
result
};
val result = new DistArray_Unique[Long](Place.places(), initializer);
val pi = (4.0*result.reduce((x:Long,y:Long) => x+y, 0) as Double)/(N*Place.numPlaces());
Console.OUT.println("The value of pi is " + pi);
}
}

123
samples/X10/NQueensDist.x10 Normal file
View File

@@ -0,0 +1,123 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
* (C) Copyright Australian National University 2011.
*/
import x10.array.DistArray_Unique;
/**
* A distributed version of NQueens. Runs over NUM_PLACES.
* Identical to NQueensPar, except that work is distributed
* over multiple places rather than shared between threads.
*/
public class NQueensDist {
public static val EXPECTED_SOLUTIONS =
[0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712, 365596, 2279184, 14772512];
val N:Long;
val P:Long;
val results:DistArray_Unique[Long];
val R:LongRange;
def this(N:Long, P:Long) {
this.N=N;
this.P=P;
this.results = new DistArray_Unique[Long]();
this.R = 0..(N-1);
}
def start() {
new Board().distSearch();
}
def run():Long {
finish start();
val result = results.reduce(((x:Long,y:Long) => x+y),0);
return result;
}
class Board {
val q: Rail[Long];
/** The number of low-rank positions that are fixed in this board for the purposes of search. */
var fixed:Long;
def this() {
q = new Rail[Long](N);
fixed = 0;
}
/**
* @return true if it is safe to put a queen in file <code>j</code>
* on the next rank after the last fixed position.
*/
def safe(j:Long) {
for (k in 0..(fixed-1)) {
if (j == q(k) || Math.abs(fixed-k) == Math.abs(j-q(k)))
return false;
}
return true;
}
/** Search all positions for the current board. */
def search() {
for (k in R) searchOne(k);
}
/**
* Modify the current board by adding a new queen
* in file <code>k</code> on rank <code>fixed</code>,
* and search for all safe positions with this prefix.
*/
def searchOne(k:Long) {
if (safe(k)) {
if (fixed==(N-1)) {
// all ranks safely filled
atomic NQueensDist.this.results(here.id)++;
} else {
q(fixed++) = k;
search();
fixed--;
}
}
}
/**
* Search this board, dividing the work between all places
* using a block distribution of the current free rank.
*/
def distSearch() {
val work = R.split(Place.numPlaces());
finish for (p in Place.places()) {
val myPiece = work(p.id);
at (p) async {
// implicit copy of 'this' made across the at divide
for (k in myPiece) {
searchOne(k);
}
}
}
}
}
public static def main(args:Rail[String]) {
val n = args.size > 0 ? Long.parse(args(0)) : 8;
Console.OUT.println("N=" + n);
//warmup
//finish new NQueensPar(12, 1).start();
val P = Place.numPlaces();
val nq = new NQueensDist(n,P);
var start:Long = -System.nanoTime();
val answer = nq.run();
val result = answer==EXPECTED_SOLUTIONS(n);
start += System.nanoTime();
start /= 1000000;
Console.OUT.println("NQueensDist " + nq.N + "(P=" + P +
") has " + answer + " solutions" +
(result? " (ok)." : " (wrong).") +
"time=" + start + "ms");
}
}

117
samples/X10/NQueensPar.x10 Normal file
View File

@@ -0,0 +1,117 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
* (C) Copyright Australian National University 2011.
*/
/**
* Compute the number of solutions to the N queens problem.
*/
public class NQueensPar {
public static val EXPECTED_SOLUTIONS =
[0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712, 365596, 2279184, 14772512];
val N:Int;
val P:Int;
var nSolutions:Int = 0n;
val R:IntRange;
def this(N:Int, P:Int) {
this.N=N;
this.P=P;
this.R = 0n..(N-1n);
}
def start() {
new Board().parSearch();
}
class Board {
val q: Rail[Int];
/** The number of low-rank positions that are fixed in this board for the purposes of search. */
var fixed:Int;
def this() {
q = new Rail[Int](N);
fixed = 0n;
}
def this(b:Board) {
this.q = new Rail[Int](b.q);
this.fixed = b.fixed;
}
/**
* @return true if it is safe to put a queen in file <code>j</code>
* on the next rank after the last fixed position.
*/
def safe(j:Int) {
for (k in 0n..(fixed-1n)) {
if (j == q(k) || Math.abs(fixed-k) == Math.abs(j-q(k)))
return false;
}
return true;
}
/** Search all positions for the current board. */
def search() {
for (k in R) searchOne(k);
}
/**
* Modify the current board by adding a new queen
* in file <code>k</code> on rank <code>fixed</code>,
* and search for all safe positions with this prefix.
*/
def searchOne(k:Int) {
if (safe(k)) {
if (fixed==(N-1n)) {
// all ranks safely filled
atomic NQueensPar.this.nSolutions++;
} else {
q(fixed++) = k;
search();
fixed--;
}
}
}
/**
* Search this board, dividing the work between threads
* using a block distribution of the current free rank.
*/
def parSearch() {
for (work in R.split(P)) async {
val board = new Board(this);
for (w in work) {
board.searchOne(w);
}
}
}
}
public static def main(args:Rail[String]) {
val n = args.size > 0 ? Int.parse(args(0)) : 8n;
Console.OUT.println("N=" + n);
//warmup
//finish new NQueensPar(12, 1).start();
val ps = [1n,2n,4n];
for (numTasks in ps) {
Console.OUT.println("starting " + numTasks + " tasks");
val nq = new NQueensPar(n,numTasks);
var start:Long = -System.nanoTime();
finish nq.start();
val result = (nq.nSolutions as Long)==EXPECTED_SOLUTIONS(nq.N);
start += System.nanoTime();
start /= 1000000;
Console.OUT.println("NQueensPar " + nq.N + "(P=" + numTasks +
") has " + nq.nSolutions + " solutions" +
(result? " (ok)." : " (wrong).") + "time=" + start + "ms");
}
}
}

73
samples/X10/QSort.x10 Normal file
View File

@@ -0,0 +1,73 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
/**
* Straightforward quicksort implementation using
* naive partition-in-the-middle and not bothering with
* well-known optimizations such as using insertion sort
* once the partitions get small. This is only intended
* as a simple example of an array-based program that
* combines a recirsive divide and conquer algorithm
* with async and finish, not as a highly efficient
* sorting procedure..
*/
public class QSort {
private static def partition(data:Rail[int], left:long, right:long) {
var i:long = left;
var j:long = right;
var tmp:int;
var pivot:long = data((left + right) / 2);
while (i <= j) {
while (data(i) < pivot) i++;
while (data(j) > pivot) j--;
if (i <= j) {
tmp = data(i);
data(i) = data(j);
data(j) = tmp;
i++;
j--;
}
}
return i;
}
public static def qsort(data:Rail[int], left:long, right:long) {
index:long = partition(data, left, right);
finish {
if (left < index - 1)
async qsort(data, left, index - 1);
if (index < right)
qsort(data, index, right);
}
}
public static def main(args:Rail[String]) {
val N = args.size>0 ? Long.parse(args(0)) : 100;
val r = new x10.util.Random();
val data = new Rail[int](N, (long)=>r.nextInt(9999n));
qsort(data, 0, N-1);
for (i in 0..(N-1)) {
Console.OUT.print(data(i));
if (i%10 == 9) {
Console.OUT.println();
} else {
Console.OUT.print(", ");
}
}
Console.OUT.println();
}
}

View File

@@ -0,0 +1,123 @@
/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2014.
*/
import x10.io.Console;
import x10.util.Random;
/**
* This class represents a real-world problem in graphics engines --
* determining which objects in a large sprawling world are close enough to the
* camera to be considered for rendering.
*
* It illustrates the usage of X10 structs to define new primitive types.
* In Native X10, structs are allocated within their containing object/stack frame
* and thus using structs instead of classes for Vector3 and WorldObject greatly
* improves the memory efficiency of the computation.
*
* @Author Dave Cunningham
* @Author Vijay Saraswat
*/
class StructSpheres {
static type Real = Float;
static struct Vector3(x:Real, y:Real, z:Real) {
public def getX () = x;
public def getY () = y;
public def getZ () = z;
public def add (other:Vector3)
= Vector3(this.x+other.x, this.y+other.y, this.z+other.z);
public def neg () = Vector3(-this.x, -this.y, -this.z);
public def sub (other:Vector3) = add(other.neg());
public def length () = Math.sqrtf(length2());
public def length2 () = x*x + y*y + z*z;
}
static struct WorldObject {
def this (x:Real, y:Real, z:Real, r:Real) {
pos = Vector3(x,y,z);
renderingDistance = r;
}
public def intersects (home:Vector3)
= home.sub(pos).length2() < renderingDistance*renderingDistance;
protected val pos:Vector3;
protected val renderingDistance:Real;
}
public static def compute():boolean {
val reps = 7500;
// The following correspond to a modern out-door computer game:
val num_objects = 50000;
val world_size = 6000;
val obj_max_size = 400;
val ran = new Random(0);
// the array can go on the heap
// but the elements ought to be /*inlined*/ in the array
val spheres =
new Rail[WorldObject](num_objects, (i:long) => {
val x = (ran.nextDouble()*world_size) as Real;
val y = (ran.nextDouble()*world_size) as Real;
val z = (ran.nextDouble()*world_size) as Real;
val r = (ran.nextDouble()*obj_max_size) as Real;
return WorldObject(x,y,z,r);
});
val time_start = System.nanoTime();
var counter : Long = 0;
// HOT LOOP BEGINS
for (c in 1..reps) {
val x = (ran.nextDouble()*world_size) as Real;
val y = (ran.nextDouble()*world_size) as Real;
val z = (ran.nextDouble()*world_size) as Real;
val pos = Vector3(x,y,z);
for (i in spheres.range()) {
if (spheres(i).intersects(pos)) {
counter++;
}
}
}
// HOT LOOP ENDS
val time_taken = System.nanoTime() - time_start;
Console.OUT.println("Total time: "+time_taken/1E9);
val expected = 109702;
val ok = counter == expected;
if (!ok) {
Console.ERR.println("number of intersections: "+counter
+" (expected "+expected+")");
}
return ok;
}
public static def main (Rail[String]) {
compute();
}
}

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>42fc11d8-64c6-4967-a15a-dfd787f68766</ProjectGuid>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0'">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
<PropertyGroup>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>$(VersionNumberMajor).$(VersionNumberMinor)</MinimumVisualStudioVersion>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<Content Include="css\browser.css" />
<Content Include="default.html" />
<Content Include="images\icons.png" />
<Content Include="images\logo_150x150.png" />
<Content Include="images\logo_310x150.png" />
<Content Include="images\logo_310x310.png" />
<Content Include="images\logo_44x44.png" />
<Content Include="images\logo_71x71.png" />
<Content Include="images\logo_badge.png" />
<Content Include="images\logo_bg.png" />
<Content Include="images\logo_splash.png" />
<Content Include="images\logo_store.png" />
<Content Include="js\components\address-bar.js" />
<Content Include="js\browser.js" />
<Content Include="js\components\favorites.js" />
<Content Include="js\components\navigation.js" />
<Content Include="js\components\settings.js" />
<Content Include="js\components\title-bar.js" />
<Content Include="js\components\webview.js" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NativeListener\NativeListener.vcxproj" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
<!-- To modify your build process, add your task inside one of the targets below then uncomment
that target and the DisableFastUpToDateCheck PropertyGroup.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
<PropertyGroup>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>
-->
</Project>

1053
samples/XML/sample.csl Normal file

File diff suppressed because it is too large Load Diff

213
samples/XML/water.tsx Normal file
View File

@@ -0,0 +1,213 @@
<?xml version="1.0" ?>
<tileset name="Sunny Beach">
<tile id="0">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAABYklEQVR42tVVq47DMBDsp/hHDxQcOFBwwMAgwMDEIKAgoCAgUqBhqH8l50126lHaq9TrQ7pKq8TOemd2dtfd7f7rz3TTbNpibpyNT/N7gUOxSHbKs+mLlW+vAwaQJ1B5ulQN+88kYkIJ3GhwkVwyFRABvKbEkKvfI0TOGYkha9nDe4AiqfqIHZUoznbTfURwYA1agn+rvAL2VRpuX8ym1Rw9QUpIiB/WLQilRZXfgXuVziro51hr69HxtPZUAlk3ui9ErZYNvvLeEplAU7MAx00tj3mVEhkMuWYdVeZGQTrtCZTDqz8IsAotleqCCDcUZ7aQUduSsanKjnVDe44yx9Qogdvj1k21m08KDiltqllAdnwX+xgvRzNqvLuaUQ4EDSCgB8oQtb4GxIBDfvxeOE9ApO7mUjltWl5HvQfiMy+kXhXBjGP8DhsF2rTYa6/kQKPFV7Sf3vinFLQX3Np0f43zA259mZw6IuSNAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="1">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAAB/0lEQVR42tVVLYvDQBBduTJy5drIyMrY/oOTFScrKioqKioiwhFxcBWFVhQaU0JEOCIKPXFQGVmbvzI3M/vRlIM7ev2AKwwNk7Bv3nvzEiH+7S/dQG/dg2gVQZRpeBiuro+g8yPI+R7E8A3EQEC0jkDPNdf9gLcIvGtBr/Efr4k9lUoVxGUMYaJAZaaofzvgvAG9ahhUl1gfLYisADEpQE6ksWFrFIgWEcixhHAVXq+IXlhQKsuae3gtZoVnT/47QGKvZwEPxCqMBPcvUoQ9rh0wAr42BpjkTw+gp+j985IVoIOZ5VhAv+p7sF5p+kES+Gd+HYSkZYnnFjQ5GGDLmu/htRhtEBBruGRgqi6QnEkPqKxFdN/1SLEzaxjYSe2qwl5ltp2BP1szGJbCfSALeJCRjSKmgOQncAKL85j3g/qcELLFPuOG8eqdlq0zQN7xnodpQZVmmKBq2ALHjBgFCECH0y7wXmwjz5R6POQ8hLiKvQo/x622rEsbvcrETybvIJ4w+9PibMlUYsAJWE0VD+Ei6Qa5OBU8QG6TQPJnDQTpnv0PUwti2bLvC8OMpBdDYVJCqbhJHHdmT8TASK9Ty8hGjpmujN+8Ayj1N4+vfiHRCyjB5Ru88Oazv1l48hR7DLwIOYb3+xiMlp4d+U5yx3Xs4/ewjxLtQfcl89dzvgD75hkn04cPugAAAABJRU5ErkJggg==
</data>
</image>
</tile>
<tile id="2">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACjElEQVR42r1VIY/iYBTkZ6ysrURWYpFIJBKLRJJTVZsUQcKKTajZEAQhCBIqmrSCpAiSIhCfQFQgKk5UnHk3876W3Iq7bLjdJXkp/dow8+bNPFqtBz+d2EgSjaQs5pKfJtL6ro93rqR7EuluS+lFpSTpWMx5ItlxjPpCIs5bLm5UiLcrZVmI+BcB+ATgvlQ/F5LEI1UiP40/VxEnzMR5QYGAd6jEOxvx3ox0VoVk6L4s50ogO0CJSyCb9UC/a0GV/W74GBlnZkG1Xu316TmR7nQv3bQSY5bo1FcgksgxBnPhfaPERJZhX58X1+DjJJwtwLYNMEg8o0hmZ6Q9y2WwrmR5E1WABmSHSTqSqlwoENUgGZ5xLMYEksMbfC/HuP4OHBlxVgCd1qA/EgvMogJryB5VMkD14IN+Kiq3zh6ABNZRANiOw1dTFte5ktlH9fnZqvYeuJG6KYA5a1zD3JJKC3Ffclu4J3j/INJbGZFfSy0CslOmoqiV4YhYJEm/6LUmV1AZPLMmQ6YpsYKz42ndNa+hBW6/Gn3G+I0ZQ4BT8rIIABjc5eYZKz+OLQGSIvDRArM226ESfRdb7bZRIPzDfFuj8WunpQzOkL1EBAsrP+Uk0F1eyk4/YBQkRflz3RETu7Rudmnx7J95VxPG1hNubMGfZkgAZq8RDCG9bDR2/PEstbNVJVKbAhvPOVTx9ayJ5sfTQAIYjwupvXUhvRjOBwEXY1A5jTUTu+G8lYiqMcT96L6gtOv/2ZAuuu2gYRdjGR5FFWBH9+xj7kZ3QKCxJClrzD3eWXzeRuTy8a9wP/xAiRtD6UzZPRfOJagN94X/Cb24VBC6mPJmBxKwbv/Wf0Wu3PK2UKdT/kd/5zeaE2gm63UKTAAAAABJRU5ErkJggg==
</data>
</image>
</tile>
<tile id="3">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAABvklEQVR42tVVr2/CQBTmb0XWVlZW1lZWoicWMkECgqQIklY0acVEBeIEomICe3vfd33H0Y1kY0AykpfCcbzv17tjNvuvr7ZLbbmL7fJlbodjYZ8GbA65rQS42ie2f88Izs91IpU+jki5jW3f57YVkPUqssYU4oC838Qkge/bJpVK+LwbsCqFOnMoaDvKgWEtF2LZ6Ehul69zvmeJKzcDAxRqoRSK2yZjEUwInD4Wjgyc6TKCYX9Irto5IiD5K2DU8i2y5SaixVQjzQCkmQMsdOY0LEhuEMI6oNPYWvn99akWxuWYJxV0yDfywLBX1VWBM8NQuGEUAn4gJ7GhB/pxvXNxBYq/5oYnWJOEgKAR1kFovYp9HFCI5krCRZCQXDiY6kSvJGSvgTNN4Mh3thGodg2MEIW9aKBOADiMiarVAVEK9XQJZCbuXp/60TZjcj6x2ZFJSQJk1AmAaEzqhq7r6UCVI6kL639y7n3jiW3lNmJsdGokyH114qPi3IxD2/7lgro4FTt32zkw54qS4PrmrLStEw7mXe9+r7o5Dyczrd1waUQPvZL1uOpwVXsQyPycPO1PCTkPxwUHFUf51j6f/7okyrolgPYAAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="4">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACUklEQVR42tWVr2/qUBTHJ5FIZC2yEomdRCKRtVUvVUsz8dLMMUHSiSXMEDJBGgRJESRFkBRB0oknEE8gJvgXzjufU+4eZsl7+5Vsyclt77m73+/5nu8pFxff9a991xZ/5EvzuinJYiBfBty6aUk060k4uZR4NZDhNpDw8VIg1LnvfB4R79aT1nXLgCAQzfoSKInurCvZLpJ40RfOuPi4in+2hACgcdUQb+SJf+NJ8NCV6TqU6aYOiBj4VVP8e19Qiva8GXj/K5FqG8vhkEq+CMSf1JdWu0TSdWCgibYA2WlB9NizM5BwZFjJ/5ciABPZvAbNl6GUm0jKdWQEqB5iUyWRK4lcc7G2BJB42TfAYhtJtgqMAHewWqhqrwJXu1gKBTs+p8Jz9RQreCCNHw3ZPyUmZ61AnYNENO9Ze9gnkuXAgMcajhSEjMht21b+hyLOKh5KNhtYlUhZKnueAeAC5C/1mYsgFDzUcpODGN4ghyJjzac6kuYZVSOcdF+IEJxJ533DQQ2K+6uAVlWoqYpVKPv90AjQb1b2Dkr0qH6AHOfoP7nOqG3nbX9XFzFVBVAjcW3AtHddI8UUQfDVVlDtcBOo+YZy+J1KpqydGpBAapTIF6HKWVdDDpKstJB9fMQ7gOcj/M9m5EKMZ6tWx4UHlFFVCq2MtplSJz84tx+fx0ac1tIiqseI7xrHUo3HVBRKyPmhPKkCCT5MvBeniWG/Ui8dj+OP+yBR6UvVSsiZ06ZCVwdsiun7p32SM519KnUfJ6SutsnJtPHX/ShhxPN+v/WeP+Pal6x1OIpVAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="5">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACTElEQVR42tVUr2vrUBSenKyMjI28MjI2MrIyMjYyaoSJEepSUWhEoc+UMlFKRaAVhUwUOvFgExMVT0Q80X/hvO876X2rGlvf9mCBQ27Opff7cb7bq6vv+qw3iRx/T6X9NUaV8t+Al7tUmk0q6zqRfBsr+H6Xy9Mj6mf+dUSennNZLmI5HEoFIoE9QNNZCCfG0jyk4g5dabap9j8N+PBSyB6Ay1UCkEwP9ye+vgmY1311Ib0PlRh7XuXBkUyOx+nlRFQJAPW9y4REWqhvtok6oT26AWem6K0xGhLjKOYPiWT3fYnrUMzAFTMz7ydCZeUukbYtNWDnituXUrrwjcUZOB34JlYXSJTquTcHmRC/MZVRN9h3bh1dvzljzpEHqTINVaFlVVvFtDutIx2JP/K0T0cIzL1s1ZfiRIzkvYGna+7x7dw5r0SyRaTAnB9LlbdjDRn3qJyq13WqB3ezLnBQLMkkgNWR3obmGePC3OMfgSSLUIH5e6veTEzXm0VKwoyMBvjVAYDzetFCrglkU22tVdvPg3YoJMahcQVQHBbOfAmrDsgC85wSmTBDT4JFoH3m4s3Us5h6hufc2jlGoXmA9UusUygMoCw8qck3nUNqOwhmGBOLoAQP4M67w5itIs2BHQfJdA4UmvJ+BeWrUMuH8ilGQmBabYvf3OP74uvIwLBI4PrmWtxRZ2ECNTy4d9v7m3AqdW96SL+nZLn3aX9I51fJqqKt/O4BlD0lcKov+0umMmt1+Ygc4BZwrcT+xeqPPgT0ht399kbexcB/AEhbiVW/ps4pAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="6">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACOUlEQVR42tWVrW/bUBTF+2cEhhoaGpoGBgYamhoaWgOTFeaCSS6IlJEoKoiiAksNiJSASimIlIACgwKDAoOB0bv7u3bc7qPSlq2VFunpfeTl3XPPOffm4uJ//RyOiWy2kSyvA0lXI3m3wNVjJjsNvLuLpXxIpX7Km/19rCN5OyCbdSRlmclBg9wWoVRVrgzoehU1IBRQ/7Iv3Dvs/yGQU6ZkVz3mRjuDIAwYKcvUALAHhK2Vkbqeng8kXQWWLZmS8WGf2rBgCuDrl2kDBmaOqczXoXgTz34z34YGJF4MxR33xZ25vw+EbBnLm1A2q9AoJqPdNrZA0A24cOJLfDPsmGFNUL6f30UdEOfKsfPeh56tX3e10rdp9TR6j+gbdoHLh8wyZk/WnQnrvJ2nnSFhgzOAZLqOZ0ML3hs3IHofe89AkmIky0XQZMm4j1sNWxBKP1lyD0Bkyx66mfmtmVPvDj65kq4Dkw3qgyvPZIgmA3EnrjHnjB0DkRaBTPW9n+r6pdtNd505q5SBuso7OQBzW0RK/chkiq4HBpLAxpiOZDGy80ylcC8d8Re+ycGd113falpVmc0Aa8AkBgKtYYWHYAEgyENAHiY77kAzhuUeg+D+Z1/+qO5/1LuCGWWFMx6FKXQ1/6xPzSg22qGb7L2ZZ0DPLsfvqmLbdDuCYTACnMrPzlUKPABgfPBXfeBXvb8z3P7ZnFYxOhOUeqc/vGlLPpUrAKwnFDSstPPJu/0pYb76aWpGxYTnvvMN/STd514e0SYAAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="7">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAABjklEQVR42tVVsWrDMBDNp+i7+gnZO3UqoUMoHQL1YKgHgbWYoKEUD4Z4CHhUN636FVV30knnkBYSnEADRwKS7r179+6yWv3Xj+itFzpEPXkhjb8vsArRsRicf1d7jNsBJyAhCyh+18Yfvq3f9wcksN6++vXzZjkiQhkvGhPBQHKZwAMwKAHg7ThlApvdRyYBal0PXJsisYwgAJAVOAFv9ddMhYfHp0i4t5cRoQcROJDYJYmHklxUBoMDcxUyAZVUg+jCm9H9TgQO8WIVQcXLFGU+6TFJjORUJEZndI7gTXyLisFvzcgoNjXY46ObmQpJyEgGKoMqITlXAXssbfYCEQeysztkWMoPcXTniLCxUqz3w5SrbEczr7JK4InsOaWQhGZTI2P8PW49YwkPPx0SIZkpCZxRxbxVdDd7gaq+yIzwQKVJgErfUmsakwnM5j9Uimr1xRMIPrgFxpHk206lTckrBE6uJ3A0dWcXXEhjUkQXf+TNqJl/tMG47UpWbLT4ipb2jn9KKnmhjvvi2jw/5gK11tLQbjMAAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="8">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACOElEQVR42tWVr2/bQBzF+ycMBoYaFgaGBhoGGoYaGgZN0cCkDERKQaWGBBhEVUGkBVRywCQHRDqDAIOAAwUHCgxG3t73e7nVqbQf6tpKi/TV2U7k97n3np2Li//1Y6oxim2K2zyBe5jj3YTtcYqSwuW3DPVhouJ6vss447cDKe5T1PUUhiJf1yNYO6cDPN6kCiHfm/2Yk+n6asJhp7I7e5yr7TJeTK5NCTY5OTLF7SrRYx268mLhXm4x2AHxIzDcNxSb6KgYAZrHGw8jzlQTFRN32nDl1oMI5F8Ld+8MZPoU7W8d4gOQNdCby42cu1EAOW870/C6wDlGEwr6PDZD0F8Lb2p0c4NoZtBbcve5Q39NgIoOfAdGRyCxQEpX1HoKyU2dm/syEuBnIZ/FJk4IlF6vfFznwktzPqsavY1TF3pbH8Xw4DDY0w1GktTQOGSHcvMA4SPIFK5dzOBEHSD4WyvO7FuOdBctgHB8bdD5WODyzjKOBjFdESBxIqEzqayMaESoEXxX9HEMIkfvkoy4IVDaj+o3T4kKSw/ufSTdWakwceU7ITCJA4+tuhTTjf7OR5XUDYaMagwfWXhCilMsZ9b/sYwCsPDinSuun0qEJ+NDXrKcjT/fcF0RhhAiPhCQB66O1wmnu/6XF5Q6sD71hHGEmDrXJaJlrQ5FVwaXa6sdESBxYyAQhH21F5KWVRzJT/34UqLzudCOhJjaxX2zV3IoabR4KqxEIjHJvNufUpSfIGT3s5cL/wB3sgL2s65DmgAAAABJRU5ErkJggg==
</data>
</image>
</tile>
<tile id="9">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACYUlEQVR42tVVoW7jUBDsJwQGmhoaGpoWBhoGhgYGGp2igpN6IFICItUkqgKiKiBSDCo5IJIDLNkg4IECgwKDAwYlc7P77F7InapeW+kirTZ5D8zszOzL1dX/+vGTAulhguppjof1EF8HXDYIn4HBocGoBIpyyoqQnSas6POIOHEBZ8tKDIYkMMwBY+aoqjman3dIH8co8og10f5hwL3ZHv3vKYSA+2jg5TX8Y43BETp1/TwnkalWdpzgYTPUrsX79088y9BfZOgtUvT53VkX7Clc9rEB/F2FQSW9Zg5uYWiFAKaHTokI93GoROT+zcDuhpOynFWhwP2bVBXwdgbukndLA39TIUgaS4CZcI8V1anQ1HdWjfNUiYgtxtyiYDb2u5Hm5c/AW2On/JFp9QgsKjgLS8TjxN6KJGiFTO2faoxqZoF1zUyM2cMz1JKM4DK5EJEtETL7pD0rrVW/pWaoZNrLcjfGqhC3Zy0xISBEglOD4NzYPLAPSGAiRI7cEG5G+AINp5ARFaQyrqz2jpgok18o8gq2ugBeWvCOlJdQ6q2oYNQKb0VVaIe3rXB9qGlLDYdBlTUVYjKtKKAqUAEhpPko/7IlFqxQzwX81RrJA7PQ+9aGUraCBBU8b7TL9O6hQiRqPNEe/sbLvX0n2s14+xZwEifOrBKU37nJtAuozQTDSFBnYc/EmgEBAyoxJnjITbn0/p/W0dnZnMhGdDb1l5Zcp4ooEPB19NZU5MTpSUI8/7iXMGkVaTOh2yLg3bbwzGcGAtrhU4XPe5LbkLrxZWDtoyX1ZX9K8iIqCZl+9n7gXyTF4JLCnrXHAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="10">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACQ0lEQVR42tVVoW7jQBDtp5gaGhqaGgYGGpoaBgaGBvbASSmpTgVRFWCpAZFiYMkGkRxgsKDAIGBBgMGRd29mbQdVV7W9ShdpNJvx23nvza6Tu7v/9ePtGvg7A/+hgfezwvcR5yR9MvAem1uw5u0ZFPXviIWIJAHJ/S1zaTX7PxqETx3CbXcT85VCpKmOmTnYk+jcI6itEsskgrxDVPRILeAXFl7RwWfNO3xSiCcE28Et3QmR/2AQ5hbhwSJi+CQLBhEhI9gxKCI4OIz7zn0U827ikO7iVyA+gSQ9oi0bPRp1HnM9z4G0BeZ8PiuJI2Zecy01iTOQFMzsMROMAcKSU5O7QzFvE7e9kkqzhHnBjSmbROKYEbGWGEeado5oxojqHlnvBCWCN66HiJH9ijs5Q7HgmWU6E7Fp13jeJgqoygWaekkQxbQOKOpnV2D5mwStcxoPbkVQwvqsc8SZdfWA05Je/XWD5rxEc1pifiGWz+NymBS/R+w9CRHgschwPGQwZq1CmtNKszQTkv76S9eCk6bW3uNln6IqFlo37YrrTNcV93WvfJ6nsJd7HPeZZtknXG8exbix69aa1UHtXHSclggU0pecQs+rYZ0qYVUvpmci3hgXx1EU492XUYjEmebBXSeTYePjIdVj00kNAhVXLyYRIk5CXdfLj7+OQizxvEvpxI3WkbmpjCK0vr85bSjE2s3X/SAJyeSaxOPY9UyHezIeUfUZx38VcnJOx8tVlSJgNd2Tb/tTknO2l41eVHmVP9rnD/NFCxuaQAv3AAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="11">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACIUlEQVR42tWVrW/jQBDFCwsPFi41NDQ0NQwMLCy9vyLgwIGCgIAAEwMD62RgEGCpAZEcUCkFAQYFhgYHDI5M35vZ9VWV7qT22koXabRrOTvvN1/ri4v/9efqk7gStr4Tt+3kc4VzWHGSqO7NdoO4XS9893HCEKRIVMDKXuLDaGuOZwCp4dk17wzi8k7cpjPnFcT2AwziG8vCbChH1CITbW+l+deMuHU3O3Zbi46iIdIYMGkvktSDLM4iiyP2u1GS4yRxC0C81/P16XUg4YBGRDGARACIGfU37FedgXgYdwvQAJsbrFvdGUDu/QQYZOXPwj51KriG4HcY6p3UiKqBHSaNNuW+GXSvZQnCKJOu7AH6IDzBS+sRLV/ty1g+y4jWqnhRT3Y2ROJq0DU6jupMo4aDGF1PxwTkBLD2armHYZ9QnA1a2JkwMZqhrS9t/mx8w2iFiFSoMoG49SBwkJwndUxxXZkNwnpAhSp8+TYWuVrjA/UAfx+32kdBaoozyqKfnc6j6FeFK3y6V92cLbf5fWdoiV/TjBHmPEE3pwBJykGyBj2AkqTsdFiKTLAfUvYI+iHZ2/+ZEb2kcO5L1clVdZLL2x9vH0cVwZgpTAGA/WRiAYSrLwXf8XnxIBIdrEnf7UKK0YgZZvx6FLn5KXJ9NlvuRbJ20rtg+Yj9AyDux4+7kimU4dJZEgAgX38hOxDNDqIZ+LSPEtO8uIdRePf2iJ8AkT7BKeWMTHEAAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="12">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAAAhklEQVR42mNgGKpgztI5/5Ex3S2u7mxGwTR3CC6Lae4QYi1Gx1GZSWBMscVAJhjDDCTBYjAmOUTQfUysQ3BZTHTUEApqXA4hZDHBNEJqHKM7hFiLCTqEUBzj8impaYVg4kQ3gNggJuQQknMFqXFLyCF0LweoXiCRUQ7QBhBRDtAHYCkHyAIATRZdO8VgYzoAAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="13">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACNElEQVR42tWVrY/bQBTEAwMNDU0NAw8eDQwMDDQNDIwKqqisBZbOINKZRJGBZRlY2gORHHCSD0TaggJD/xuvM2+zl6hqq7b3ITXSUxwr8fx2ZnYzGv2vr7DoJCqsxFsr44+VvJtwd1xJVS4k3HYSl71MT4OEpZWg7GSct28Hss/n0h6WUtULud/OpHtcyb5I5KYeJM6tRBmAil6CXSejzLweCFdrHpxwd1zLfjfXMXUipklk0gxyexwkSNtnJ4IMTtCN9AXRtF4UK+WKTbPUoQv7Yi79t42DgTM3DwN6YCRCH2JcTzCEGH8yzo2/AaEwRe7SqdznMxWvigVE6UQi9rRWAMJ5Z+LMukLu8I44psWgUGHq3Bh/MYCpnCu/etFOCtqntXs4P0PcC7eHlbMe96+d6fvPMkEZ2QWKx4jjtmQvepmgE4RSkPQMghld7xq/Wgox78u4jO+ymQrynjqSXeLQCOCG/bpR17SIEIwfBxUn1PQJbhwAB8gwx075ULn5EYRiPlPfdooQhMJ0oKM7APFOMI7rmPg70ywkAgRd4RkR1xBmNE2vMYWA/O254dtOi7nnKeQb72PwTrQA9DF5N3hfhTm564ZGA1ei2v55GZ8fmDsBLacCLfUeY2uPS9eJs0s+Pl4H2JLRoddOBLv2Zdvx0hPXfsJpR+DMTyFYXHyPW/XVDiQt5HnVVe12iIfguA64iAj5ZkcyxTSC7LxldbWJQhHy3f6U9Mw4bVDWta78X5/zHZ1ZvLB/eOxTAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="14">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACSUlEQVR42tVVLW/jQBTsT1lquNAw1NDw4MHQwEKjKjqWgkgpqFSTgoCAAEs1iBSDSDaw5IACg4IFAYamrzNvN70rqO7UL+kijXbzIc+8efNeLi7+15fZdmLWwHIv5raWbyOOyl7MfSfR2p963zmJmgFn/3VClBDk0T2wASqnIuKNk0kxyKQEDqPERwBiPs/qvBZzU/tqaTmqNUUvNge2TuJdIIYAklsK2Pn7BHg/8bLWClmtuQ3kN506YAunhIkT+XEUmVQgoxCe7SjJIz7vAXxPEe5p8e9CTAESWG1Lpw9NylER48HxEp9fd2IhgrYnu1HSSvSkC2kQM21F3+93M+n7hXRNJg/FVLrj/G0h7K/ZgByVm2tUf1VLvPb9jYEIVdvQc62+8raTSFuB36QgnopIehCtugaxe1pJXV2CPJP6cCk9RPB8TRzSfE63ksEB2s/TIlQWbYgA7W8zauhiEvMOy9NB5Cdsn55EhtMdsFIHujZ7caI/i3ici6Mz7R+OmPy3iJc7e7/1ghRM/wHEaAExgRusPml81dqSxtvv3AJYyUM59WLKmZ4URDfebgWJuWQw0xo8JF5FBEERgmhJvAntKLwLtJ9tmZ98MAeQ9/1csa9mWvkr6/8aRgrIw/ghE+aXzwZFkJzLh6N4DiNd0Gy0fgJsOyi5Vt1kHxtHdYFCrvY+F2H+mRcVUPgpoAiK4fhlCCPFfN5CKoMja58PToi2IHd6TxlEWM8tyF3wdX9CIaRRWE5cSpyS80L6vn9DuBGdhSCY733OM8S85MLHyAKwAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="15">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACUElEQVR42tWVr4/icBDF90/BViIrschKZGVtJbKyFsmKS8CsQJANgoSKJosgAdGkFYgKxFcgKlZUnHn33rTcj+Tukg27myzJZL5pE+Yzb958+/DwVX9eXsNb1xg8HjH4dsSnFfZPDYYbh+HWwc8ay17uMMgIsyk/DkSFgiswqYDgDPhFi2FGiJXDaNvAXzsD8/aNwbxb4Rhd0dABowIYXxg8T3iWAqN9izFhgopAVMdnttHcq0h9TlGeEqTfgbhhMEeXXwoEVa9C37kvFTSSvIGnsQjiqTSIN4GosOJ5E+Eli7DLYhwPU4QESF8JcaICWWtgAc+SXmMY8zwh2Chv4T/WnU96rwxuMP8bTVkkLBijuc4tu8vc4rifoq5SO6ccx5wR0Qth3SmhEajokBBDFpIqgtKzUa+Ktyw7RRQrgix/25qySPGyjyEAhXMzBiHy2ELvd9sIDZ9JifI0tWft6wLhpRvLWN5Q508svGZRjkHFBSejevtuU7xVr0T+FxD9uTpVluyCUtcah0DcefYT4gbcNHPLET0SUZGw6sx5U8WUkFkPrSljAMvS4t+jqLqOZUABlFViZ1OHEILZyRvb2IAnGoU2hF2PtRFLZ/m2mjYCSq8NeZMZ3WVm81dBU4dKuHpm8r/kEfQ+pAeStjNjzDxip/KFyX5g8XO3mt4998IfW0GgI9UwqJsqBJm6zpC2CUV/UfX3wbtdSCr2vA5RmwqJjUkQzi2QoAdQcZoy4Fg+7Eo2BWhS2wyubKS7Ad3FFBT4vI+SjNhcF2bU8I6OfwC3fgnHe4r96AAAAABJRU5ErkJggg==
</data>
</image>
</tile>
<tile id="16">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACP0lEQVR42tWVoW/qUBjF96dgkZWVtUjkZGVt5WQlFgnuzSAQhCCagGgCgqQIklYgKhAVExUTFc+cd853C1u2ZAvLtuTd5MulN4Tf+c53brm7+19XUSbY7mIs5yHCCvg1cH0eIyc43z+gOo0QPQMRgGHJOv6gkG0Wo6rGKA4J1mmEup7QgQTRGUgk4AQMKGDI5+F3OnLpNCe4Pk/MdlVxTKwEe6g7AQfg/ug++2WL/qL6uhBB1a06VcfFcWRVVSMbQfv8ByFBSUsgwTH3YN8a3NvU6O9r+KcW3qFBf3ODEIFVy1WE7SbCeuPmne/oRDlC8zQxmED3ZWc7HQiyBoNdi8FjbXuQNvAXFLFpzAmJ6K0KfGj1ljABzF6mfE0BF3B1Gl+t1zi8FUFnZ3vUsDiKsHQjCCQga01AwGd918voypwiHgurVx2PsVyErkvVwe2y30TQfgF1LkHrNL6OI6C9yoBcGAg4I3DBzumGHJAQ6z4lWHURsGDNJSTHu3v9Ou0G4q6zmkIb5sGc6pxomsm1W2/OLgnzj13nOptV1n1vRtiqctC34Hej6NJe12PbJUwiwr/AiHdeYi5OKHw2Z8LtBpzgrJ86cJ8C5EBPJRG3hFEgzV9BiznjmAJ05/WsAOrFo249ChDMV+gYOC9zoTPLVy54H4bvsxXDBStU0jVrBa92ZwJqBAPZrquXujKbP0v9rUv2D59eHLDuBZ0WNmsl3Cr9ZvDb5TP5dq3Slztu3XbJ/rU/pX7WBWyaW331d/4B+NMC1rjos6YAAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="17">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAAB/klEQVR42tVVLU/DUBTlp9RWPln57CRykv/BD0AiEBMTFTUVFRUVT1Q02QRJJ0geAlGBmEBM1l7Oue9t3QKEAIOEJSdru6Tn4577dnHxXz+J85JUwGIlSd7LnxGn3VZSEKfNIEnpAxyuW6DxvyeEhGkL8gLk9SBmsxPjtkign7AXc04hhsTlIFkLQgjIHkd1m+ZeTMM0hjAKkjOFLt7/NJH5g4i9H5U4c0AH1FsxAMnoPtuMYiCAiSQQlCCdpPaTIKLxXxOSIdr5KDJ7BNaj2HonlgLg3BZbsTlEFENAOUGToAAKuVkF8iKKUUG9pvIx8RMI4Mg2ELARmTvRa5JbprAOCdh21BRMHZxrN5jCnpwduAPZMvaCz3hdHYkpjrbGPOzk6kU0UkZOzF9CAiTht30OYmbdKJe4T10YhfYAwnQzulBQdc0e7AUcp1BFkfl7QjhTvExFIHoWTIFnhEUnMvxmMIqT+FlEjmDpA+Gyn0axOHLu4tpGAR+OYob4OW8S0Wm6DiIOZYTzzEVxFMAk3DA5u169Xc0ypvKVMnI0PHA0mQpkOVaxjNFzLdEXjiAtYtylP0UXV/Kn54I6Zho8fBb+UDyeCdp8kt/2U+v3rtsQ+flOQo6CxC4Qq3tGftufJlD1it87kqvhICCph+n4/axcZ/83LOKOL0LpvvueV8nivBN16X1tAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="18">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACQklEQVR42tVUr4vjQBTePyV25MjI2pGRKyPXVlZWHeXEQc1CKwoXU46IslQELiLQiEAiFhKxYkTFiBURJ2Lffe9NuqUcy+4t3YMrPObHy/u+731v6M3N//pruzkdyik9pDH1zyv6Z8TuuKQaxHU1I/u0EHI5NzPE/POEHIopWbukFiQ/sztybgUHsM+nIoLz7eMcMZP1asTSqV1Id+64Ets5PBnfLX1eHFnSwy6WvQRc+TBxVBHdOqJJM1DUEMgWEkIGATT8EBJxplu8CGJxYdmTeSQK85506Ujl9v1C+ONJNwjAbUd094QVAnTTy8yHX98pRm76TBRb5DmOOBORacaakZwjQt4AQ2cQUrnXhXBSui2JogLgCFNACM6mHASIhbAb8dETRQBmoVHnv2FCgxy7x2Fy1FcDTYCjcwjYW4kgqc9CAnQcpC0F25ZUaiksejgA68cuWH004Jz1XhyfIWbCOQCHEM3fh52/03uHPe53jvTWkt7ZC3KFu2DTes4LIYkXcRKiuBBgGvNUGfYF9hCnKggEuMlAkjovmDtMrIRKfK0QrWtPhHMADMHf+Hh1FPLRHlGMznChKIcwiFTrlnTqxYkLbDG7hRmHuDNJL/fsgNr4ZgST8fbt+x+jFMAiKb7H+rWWlUHFVjgjXbPN6XmMvAppMUb2l8R/CGHyk31fDhckMiKMQW/8/kUsr7mvudofkgCyIzxffiNrPw71rZb17EAt8Wl/yULCD/b0wLbjO3nrcV1dCLvBpPcHsf2jOL8BAQzkc/Yiwa4AAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="19">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACN0lEQVR42tVUr4vjQBjdPyU2MjKyNjKyMjI2srKyticWeuJga1ZUlFIRaEShEYVUFFJREVExomLEidjv3vsmuestt+zt0j24wGPIJOT9+iYPD//rVZ/GsiszWS0SsdeZ/DNic5lKBeJqP5LmPFFyvT+MgPHnCdltM2maqdQg2eSpGDNDAiPZFJmK4PP6OAZGut6NuHdKd+Yy09gJR8a9KYRNukSmslomP58xlQ8Tk5Ru6ZSO6+NEoWQQ0H5/cmKYzGmiZHz/Vlx0FIkakcGplXcRE6t1Krsi1YjprkLcJOo7J9ltMq19UnFZK5LsgatIDAFhaSXctxLkRoKjfV0IFe+6PtUBpnwDAT0x4+3dVTfJWDtzwwgByQWEcJucRTE8AFhTiBlAzABCvEUt3rz6JeRlbMZMf4ud5CrkMNJ1k2e6zwr4LgXzwynIh3R+AlHZSrgwEkFAWFjxSyNe3oi/aMR7hoCt+YOQ7lzfTnvfO/cMErAQxjpINkbUKd3ZziW6jvJWBrlVQSHWaIv7A+IvDERYR/7N4fWp7zq9Pd9OzFhiOIpLAC4jkMRwPARx0rq9AdwmhUhAp18r8ee1I1XX2FvXfz+M/fmmY/aZwbXGzMlmtMdWBUWIm+CQMWKNfN1IcLAu6vydxC8vuoyvzmGMiOOz67hH8Ixuv8DtEqRriJh3PRduvdsPiY5CdMl+6dBHjwHIgsdaSSmA8BaV4tN+yXTlE+x32bllzG8N192F4Agp6eMO+LjjH9KwCMHNaVe4AAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="20">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACS0lEQVR42tWVrY/bQBDF708oDDQNLDQMDTQMDDQNDAyqogOVUlApB066kFNlUBAQKQaRHBDJBpEcELDggMGBBQELSqbvza7dkqq9T6mRVjMZW57fvHlxrq7+10/0tRSe/qqWflbLuzXu3ZTC8yEDAJpH97VCtPmbNY73jQyOTuLcaiNO3/tUSO9zIdGX0tcygiDPzeuBDCuR4aNIckLMnQyPIh83jfRvPET/3kjvNgDwAErjxuj1Zzeuq5nYx6XEBo2tkzEghoAYPYjElZX4e6NAcdZIcna6EsLye3Tt16QgVGT3BEXKairlYSrFbiL1aSbNw0JSNJ2Jbz42TtUYACIBHFcywHrGFsqssaY96ifXrUnXAoBo/RePsBmbc+oS0xNgu0kBsBRznisUr4/ggxQw6QUwZ5FJgwigMSJ9kmQEcgoTXRedObsY8l+Nj74ZH25Oc6H0rLUQxX4ixsxVCR5jFmrGFBMPDk5ssxBx33RqrQUFqFD/tvZeWQU16JnMeH9QldVvHmkBOGkbGzQrA5CCBV9Ye6eqWLuUbZ5qznsmlVeCKxv9CMbdI9/hHJDvCAZ1APfnVRznOjVXwmmZl/upfrfNUtVwAOBqFKxVC/c1UENVRG3qAHAOigBoAFXio/13M1JuNSNhQiPNK++VzqyoucsdIP2qOAAPvZJcvAoJlHnRz7Ez5TrtDMlIheowMUF4j9G1ecVYf7UXkkp98A9ujanmPczUK9vcK8UV8PqbvZKpRvueoCGpQFvj9O/2p6QK5JMg9/zZjX8CTEsEAZI+lIoAAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="21">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAABfElEQVR42tVVoW7DQAw9WFhYGBoYGBg2RQVTpIJWChgoKCgYGBgYGNh33+7Zfo6jVZuqtJtW6ZSrk/g9Pz9fUvqvv+a4yt3zWlZb9r8H/JQyloC/bHK90z3jdwPuATYmXfuUh7cq91glPrxXEmtGXYjdvOL2vM7Vg17xHyBC6lH3iEENEMEziIPMoooJHsGkSiMEHwCUpHgPRBGnQlcpcglY9pYM++GjFhB6AUT6181U/W56nx6R575TREBLIoJLT01WVigKWGIkrLZJgU36ejt5wL1R7uEqhJHfMGbAsYdIgORkLjFUaNXENpCcE9wnrz7mxfN471CUi36CkrO5FnkL2/akgN5bEjCJmbCxieBe5I/KnVZfvMF8P7reWzJOQKiAxGKlVMKNauZ0HwRvXDd+RoDyM4bKOH4wJ/ZSrfUYvujCO7i/6ByIhoqOjj3mNOAqbTRv3O4kLJV2Z03uUzLqFMzGDa0oz971W+BngynDNjR/8VGSM2HB2f8JRvClN9IGbE8AAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="22">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACO0lEQVR42tVVLW/CUBRFIpGVWGRlZW1lJRJZ26CqlmZiaeaKICmChBlCEM2CIAGxpAiSIkiKmKhAIBD8hbt77uN1H8m+P5ItuenbbXPPueect9Vq//XHvG6SOTBV8fnPgJu9JqHaU5vMsUnNiwaZQ5N0/9eAraFFxrUh1bo0yGYC1tQi9HFGT79H78eAHR6GzVqDFvljl8y+2hbbA6h+UVdKcK9x2SDjypBvG6wMyHwZuLyPqNiEdDgktJh7VGwjqbKMKkLugBXotSictylIXQHEu3q3TgYrohX6lCIARt3OPMqWngzO1wHlq4CiZYdOx4TPvpCL+XdUtg1psgvkDGLIBYgAGKogIwjrm4oUPCRb+gKAc7ELacEEAFzuQCqmDMD8Ln+izGTLxFiBZOWR0+c8MFBn6kghGyBgpzbVujW5LahnYcXg27QjWyZzfm4COWNDkOiwzABEH4QWc7+yI7vzheDplJC2zLuxyR1blKxZvZlbWYOs2DO7sg+EnNR5JAIwbIihZRkrAls1FL3ojuXnrUFOKwHgOG0zMV/6IAF75MyqhWwJVIKqL9V91QqRd5+wxLE88bEiw33YwGS0EgDRNmk1vIEt/cM+lsCisjMp1IfDqAfK87zdAcqI9J7YhuunCcp3sO9sleSGS7behN+7jtWtWAWSBwWmVBG7diqYCduhNy02yMbo5/4gAQRbCyADx1O3IoENAaotyr+z8btEztdVhytfg0BU5eTP/inB59NxJEHFVf7qnAcPbLZlMU2ZQwAAAABJRU5ErkJggg==
</data>
</image>
</tile>
<tile id="23">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACPUlEQVR42tVVLY/iUBSdn4KtrKzEVlYikVgkshKLZMUmjBmBaAiChIomVJC0okkRiCdGPIF4YkTFmrP33DclzSa7yczOTDKT3DwohPN1z5uHh+/6115SnMo5dtsp4nOHLwO2zytUAlydFzDXJeIGGBsgbByC3HwekVMxhzErtHWK42EGa9fiQIqkBiYXIM47RLlDdJGz+SBHCNQrrQTYPq/Vdk7bpDp0JCoc5r+8E5xIIomuHUb79v1ECEq1VEoibbPUMWapEXQvG0+GzlyWGJcdEnEiIYHS6fsgM0riTUQIzNntZzjlMxxzn3dVLhTI3dZKgOSGzpBQIvsQZhbx1qkr0cEikAlzOTMh8q8doZ0nASOA2itbfhQCPbC5ru7WVwNnnFsrkc5tMC46hGdRf/Az+tEi3BpMhFh89c6MtkLkscJA8Qq7bOpVcmp/UqGS4B7UqT4noeNhfo+D9pOgkpBo4jO0kvFNwPai+lEI7L0LwV7iYCQ/Wz9/Eul7Pdx2BZKTz6wQdaKa5Pg9RkPgPqaJtCHtPDCryTjYjqnzSxkUFqOn9k7gr1H0mVq70pPEPJlUSZDMMBp9LZ/HrKPYnEj+Y9ZRiESZ9YtI4MK8bRl7e/V8raKlM2r9TGOjU3w+swIs4KFYzZNkWMNA9mF0MP9fx3sryoWq9dV7dUWcSgrpv9isVZQ9UNWFV/6hd3+vmsD9cmpE4gprp9dyLaqz9vOu5L6uWkHeCbXfDV7JdODL/ilx+dxto0Pw9/7Ob7W/DzcYBXyyAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="24">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACK0lEQVR42tVVr2/CQBTmT5hEYpGVSCwSOYmsPVnZTF3mOrGkCBIUIROEIEiKICmCpAiSTiAqJhAT/Rfevu/BwUZGlv2AZCSXu757fe/7cVcqlf/6C0dt8bqeDju9las1rj3UhMProfnAk3DS1nW9W5dGr3E5ICxeva/qqN9VJVr60p8ZiScdCWe3YnpN3XMA/5wxGQ4XRrxHT8xTS9nzebg0umYsgC2dbkNzCebm7ubnQIqNlXwVynYbSzL1wbIj/bkvASQnoLQIZTzzZTiFAjgDjHGOMey8o8/NUVOyZSDbl0i+1ZhjPPElRYMEMrNItgjA2BcLIHxOwJwKsGn2bCXZhMq8BOD8OZQUe+ncSFFESoQkcuSdbZyv8RKala8ogDWLJADAxmxSbCKVlXsZlUFh9R97jCfI57vZYgeYJJhHW1iD9TQOEJyP1wkFxqMdK/qYrQJdEzVlJHIWYpyAkqnRovnaKkMWL8tYnGU8D7SNYLivgNkYgAsHArkkwBpHBT6RjQmcGdtCAcrLAsxjYTZ2NvH5ABY55WtfZz0veP9U3bNWqLwvMVhEOo/hu1ODIMygeVCCcppBS1XgNc3U612czYrC6kj3tnyQ/qufk1fnE9lS3AbapkqBjVPJSc0Y7XRAuP+r63i4FQCUuWaYeS1dQ43PjkzzFc9G/+8+SGxyYP3Ob/V07zstcuAu9kl215UA9NotCcDuD214vT8lHkSedItDym/ET+u8AfUc39TwIyvtAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="25">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACV0lEQVR42tWVr4/iUBDHV1YiK7HISmQtElmJrCUnLlWbZsWlwbHiEhAkrCEXREMQJEVsAoKkiE1YsQKBqFjBvzA3n+k+cifuR/Z2NzmSyXt9fW++P2Zeubr6X39p3pVgHNQxaMqHATdvm0IEEwWeBdK8btjcrb8bcHvSFn/gW7RufAnnobTnbWGdOWvuPWtvrrg1bon3yZPga60W9QB5155k9z2ZrnvSuGlIb9yWRMvTUGcg80/AALjR2W0ODFpGKJl1ZJhH8m3XN9D+vGNxeEilWMVSVSM57FM5PmV/TyS8CyXMw4tK5iRNV5EsFChVpZ28I/Gk3sN6pjHcxeJ/8c0NiHGmWPfleBxKpCWCxOHxN0ToZBI6cJIxYisgHEatA13sE/E+ewJhR/D8PJKO3op0GRlgqeqrk7rwmFqUu0S4PYwXYJI4qwHDYutqtRtrqSnkim1fFmorNcfuQpOwP5nr/CmVZNk1uzdbBVnXZDb3dWkYceL4QgJylT4fHn5wBMXUFQeC25YpQsF0HctIlWNtqQfZM1KFhZI7nDJzCqtxgXfltp4DCiF6wcjoHkb6Azd+WQqS+HqlUFGq7XVzdQ3IqWLPcBapaiWiBEtVzTpjsVK1eq46qeJjZrFRUij/yfo//WhArI/vaKDhxbbRqqdgsSzyntmKGsoCgUjLVe5riwFzpHDi1deRZMRiGRsZymKJdcSlukFTey5feoC9pVp9Pk/f7oMEiFNNw1JbAN2dR3GlTjly7/ZJBpCGcs1V7pTEPjObefdhf0o03/l5Ktk2th55bZ7vlm2RtXeU/5AAAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="26">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACSElEQVR42tVVr4vjQBReWVkZGRsZGRlbWVkZOXY4FU4sYcUR1nVFIRWFrikloiwVhVQUuqLQioWuOBGxIuLE/gvfve+ls+yJ+8F1e3CFIdOZl/f9mDcvV1f/6y+89RGOQ9j7HqqnFP8M2L/zwRFOQoSzEP51V+du/WLA0SSCd+vpCG48xGWMbJUgLfsodkbX3D5jPwzYlj2kyz6CcYDOp44Cci1bD5CTwKKPh4PVNc69L57GmvtY185S7GwlqLObCpk43wn4rAczoRMDBZ+uDQqZH58yHfvHFPtdiuZliL8C5lyBOS8juL3eogWeP1pMNwZakBJHEq9NgeNzJkQSbDcWdT3E8ZChWhmJN/hlcTERrXVWcq1701VLOSco96g43yTIZ33UzVATM9773NZAthyg/ppjL8CMpxMkRTfq51yfb8CpBDtlBGMCrepTdSfjCFnZgpIA/89F9VzUzUXlgzyPYvFWriKVbgWsERdevxXqAI/COVELiam8Q3KN/B9u3jlC9SQRL2KEd4GScsqdxXrWUpBWzn66TtQtKq/WtlUnie2sLT4qbV4KtV7JSAyfWh9C5Lf33AHTQnuq/EpedjfCjOU4xD0jZNiMqJJWVyt7AhfFda6jWCZK8Afr/6ThENTdax6PI+WPfCSjqK0DGcYROKR6Y0ia75CIqj5kOKvzMRmPhiRYF60rbS/gvtaNtGV1TBzSYxyF6tTHdUJew1GgyQnqOl8sDed9S2YMYy/6LXjrDXRGWjIBO9edy34LfvpREjLn9P7vqg9kQ79shN4AAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="27">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAACMUlEQVR42tVVrW/bQBTvnzBYGDpoaBgaaGhoaHrw0HTQKkuZByK5JKoCLCsgkg0iOSBSAiI5YMCgwKDAYKD07f3e+bwUbNW6dNIsPeWcD/8+73Jz879ezdlQvVNUrCJS+Yz+GXD3NKcDAx/2mtpvCfXPqb0/ah7zcUTqrSK9DqhhkHITU9el7ACvKyUk8HlzMjxaXq8G7JRCXfeUiu2Yx50FhCNtmwyOzKnII1nLsCvvBvYXPk3uJ1SwonQdMVhCejkTF9RqRi/fM0uGlbfnRMDgTj0Qy6qYo7FEQPKPgPU6FHCsvaVn1yufHKmkiiheTIUMnEk2Ib30mTjRczSuoEKunY+xNUz0l8B4sHc3EQAMVMZQzANAlQcUfvUpePBlrRgUD+371JaRCbhCGhZwGVu2jYWUxHS2cb0Cdsrihynd3t2St2DVXz6RqUJKlgGVUMM/KtnWYh1LHBgohM2OhI1AS0Evi+mcaB0J/m7H98UlEad+mk/Ju/8spAyr1Kw2Yrs7FOxoM3U5A7hmUvNVOD543KKsFOrFJZAZdovslLP5fRRuQAqOmDzkCSjdKy5XJPGUG1u+ciibcwPvF0zC7Q5MPZB6Zf1bl+tBynmiZI87tv+oButj2W5SMFYj1m/dYWSjAjmMqP6bAwq2YhAF8j2MYEbsRExSMLxf/VTaHLUU86pn/6j6ZLeVIwGFst+5J47cx/0JnaxSV67DHgTsDrjqEfzWhZz750yajiP4vc/5ASZt46J2q67KAAAAAElFTkSuQmCC
</data>
</image>
</tile>
<tile id="30">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAAAF0lEQVR42mNgGAWjYBSMglEwCkbBSAcACBAAAb475JcAAAAASUVORK5CYII=
</data>
</image>
</tile>
<tile id="31">
<image format="png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAAAF0lEQVR42mNgGAWjYBSMglEwCkbBSAcACBAAAb475JcAAAAASUVORK5CYII=
</data>
</image>
</tile>
</tileset>

View File

@@ -5,18 +5,6 @@ set -ex
# Fetch all commits/refs needed to run our tests.
git fetch origin master:master v2.0.0:v2.0.0 test/attributes:test/attributes test/master:test/master
sudo apt-get update
script/vendor-deb libicu48 libicu-dev
if ruby -e 'exit RUBY_VERSION >= "2.0" && RUBY_VERSION < "2.1"'; then
# Workaround for https://bugs.ruby-lang.org/issues/8074. We can't use this
# solution on all versions of Ruby due to
# https://github.com/bundler/bundler/pull/3338.
bundle config build.charlock_holmes --with-icu-include=$(pwd)/vendor/debs/include --with-icu-lib=$(pwd)/vendor/debs/lib
else
bundle config build.charlock_holmes --with-icu-dir=$(pwd)/vendor/debs
fi
# Replace SSH links to submodules by HTTPS links.
sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules

View File

@@ -1,13 +0,0 @@
#!/bin/sh
set -ex
cd "$(dirname "$0")/.."
mkdir -p vendor/apt vendor/debs
(cd vendor/apt && apt-get --assume-yes download "$@")
for deb in vendor/apt/*.deb; do
ar p $deb data.tar.gz | tar -vzxC vendor/debs --strip-components=2
done

View File

@@ -3,14 +3,22 @@ require "minitest/autorun"
require "mocha/setup"
require "linguist"
require 'color-proximity'
require "linguist/blob"
require 'licensee'
def fixtures_path
File.expand_path("../fixtures", __FILE__)
end
def fixture_blob(name)
name = File.join(fixtures_path, name) unless name =~ /^\//
Linguist::FileBlob.new(name, fixtures_path)
filepath = (name =~ /^\//)? name : File.join(fixtures_path, name)
Linguist::FileBlob.new(filepath, fixtures_path)
end
def fixture_blob_memory(name)
filepath = (name =~ /^\//)? name : File.join(fixtures_path, name)
content = File.read(filepath)
Linguist::Blob.new(name, content)
end
def samples_path
@@ -18,6 +26,12 @@ def samples_path
end
def sample_blob(name)
name = File.join(samples_path, name) unless name =~ /^\//
Linguist::FileBlob.new(name, samples_path)
filepath = (name =~ /^\//)? name : File.join(samples_path, name)
Linguist::FileBlob.new(filepath, samples_path)
end
def sample_blob_memory(name)
filepath = (name =~ /^\//)? name : File.join(samples_path, name)
content = File.read(filepath)
Linguist::Blob.new(name, content)
end

View File

@@ -15,50 +15,47 @@ class TestBlob < Minitest::Test
end
def script_blob(name)
blob = sample_blob(name)
blob = sample_blob_memory(name)
blob.instance_variable_set(:@name, 'script')
blob
end
def test_name
assert_equal "foo.rb", sample_blob("foo.rb").name
assert_equal "foo.rb", sample_blob_memory("Ruby/foo.rb").name
end
def test_mime_type
assert_equal "application/postscript", fixture_blob("Binary/octocat.ai").mime_type
assert_equal "application/x-ruby", sample_blob("Ruby/grit.rb").mime_type
assert_equal "application/x-sh", sample_blob("Shell/script.sh").mime_type
assert_equal "application/xml", sample_blob("XML/bar.xml").mime_type
assert_equal "audio/ogg", fixture_blob("Binary/foo.ogg").mime_type
assert_equal "text/plain", fixture_blob("Data/README").mime_type
assert_equal "application/postscript", fixture_blob_memory("Binary/octocat.ai").mime_type
assert_equal "application/x-ruby", sample_blob_memory("Ruby/grit.rb").mime_type
assert_equal "application/x-sh", sample_blob_memory("Shell/script.sh").mime_type
assert_equal "text/plain", fixture_blob_memory("Data/README").mime_type
end
def test_content_type
assert_equal "application/pdf", fixture_blob("Binary/foo.pdf").content_type
assert_equal "audio/ogg", fixture_blob("Binary/foo.ogg").content_type
assert_equal "image/png", fixture_blob("Binary/foo.png").content_type
assert_equal "text/plain; charset=iso-8859-2", fixture_blob("Data/README").content_type
assert_equal "application/pdf", fixture_blob_memory("Binary/foo.pdf").content_type
assert_equal "image/png", fixture_blob_memory("Binary/foo.png").content_type
assert_equal "text/plain; charset=iso-8859-2", fixture_blob_memory("Data/README").content_type
end
def test_disposition
assert_equal "attachment; filename=foo+bar.jar", fixture_blob("Binary/foo bar.jar").disposition
assert_equal "attachment; filename=foo.bin", fixture_blob("Binary/foo.bin").disposition
assert_equal "attachment; filename=linguist.gem", fixture_blob("Binary/linguist.gem").disposition
assert_equal "attachment; filename=octocat.ai", fixture_blob("Binary/octocat.ai").disposition
assert_equal "inline", fixture_blob("Data/README").disposition
assert_equal "inline", sample_blob("Text/foo.txt").disposition
assert_equal "inline", sample_blob("Ruby/grit.rb").disposition
assert_equal "inline", fixture_blob("Binary/octocat.png").disposition
assert_equal "attachment; filename=foo+bar.jar", fixture_blob_memory("Binary/foo bar.jar").disposition
assert_equal "attachment; filename=foo.bin", fixture_blob_memory("Binary/foo.bin").disposition
assert_equal "attachment; filename=linguist.gem", fixture_blob_memory("Binary/linguist.gem").disposition
assert_equal "attachment; filename=octocat.ai", fixture_blob_memory("Binary/octocat.ai").disposition
assert_equal "inline", fixture_blob_memory("Data/README").disposition
assert_equal "inline", sample_blob_memory("Text/foo.txt").disposition
assert_equal "inline", sample_blob_memory("Ruby/grit.rb").disposition
assert_equal "inline", fixture_blob_memory("Binary/octocat.png").disposition
end
def test_data
assert_equal "module Foo\nend\n", sample_blob("Ruby/foo.rb").data
assert_equal "module Foo\nend\n", sample_blob_memory("Ruby/foo.rb").data
end
def test_lines
assert_equal ["module Foo", "end", ""], sample_blob("Ruby/foo.rb").lines
assert_equal ["line 1", "line 2", ""], sample_blob("Text/mac.txt").lines
assert_equal 475, sample_blob("Emacs Lisp/ess-julia.el").lines.length
assert_equal ["module Foo", "end", ""], sample_blob_memory("Ruby/foo.rb").lines
assert_equal ["line 1", "line 2", ""], sample_blob_memory("Text/mac.txt").lines
assert_equal 475, sample_blob_memory("Emacs Lisp/ess-julia.el").lines.length
end
def test_lines_maintains_original_encoding
@@ -66,508 +63,173 @@ class TestBlob < Minitest::Test
# earlier versions of the gem made implicit guarantees that the encoding of
# each `line` is in the same encoding as the file was originally read (in
# practice, UTF-8 or ASCII-8BIT)
assert_equal Encoding.default_external, fixture_blob("Data/utf16le").lines.first.encoding
assert_equal Encoding.default_external, fixture_blob_memory("Data/utf16le").lines.first.encoding
end
def test_size
assert_equal 15, sample_blob("Ruby/foo.rb").size
assert_equal 15, sample_blob_memory("Ruby/foo.rb").size
end
def test_loc
assert_equal 3, sample_blob("Ruby/foo.rb").loc
assert_equal 3, sample_blob_memory("Ruby/foo.rb").loc
end
def test_sloc
assert_equal 2, sample_blob("Ruby/foo.rb").sloc
assert_equal 3, fixture_blob("Data/utf16le-windows").sloc
assert_equal 1, fixture_blob("Data/iso8859-8-i").sloc
assert_equal 2, sample_blob_memory("Ruby/foo.rb").sloc
assert_equal 3, fixture_blob_memory("Data/utf16le-windows").sloc
assert_equal 1, fixture_blob_memory("Data/iso8859-8-i").sloc
end
def test_encoding
assert_equal "ISO-8859-2", fixture_blob("Data/README").encoding
assert_equal "ISO-8859-2", fixture_blob("Data/README").ruby_encoding
assert_equal "UTF-8", sample_blob("Text/foo.txt").encoding
assert_equal "UTF-8", sample_blob("Text/foo.txt").ruby_encoding
assert_equal "UTF-16LE", fixture_blob("Data/utf16le").encoding
assert_equal "UTF-16LE", fixture_blob("Data/utf16le").ruby_encoding
assert_equal "UTF-16LE", fixture_blob("Data/utf16le-windows").encoding
assert_equal "UTF-16LE", fixture_blob("Data/utf16le-windows").ruby_encoding
assert_equal "ISO-2022-KR", sample_blob("Text/ISO-2022-KR.txt").encoding
assert_equal "binary", sample_blob("Text/ISO-2022-KR.txt").ruby_encoding
assert_nil fixture_blob("Binary/dog.o").encoding
assert_equal "ISO-8859-2", fixture_blob_memory("Data/README").encoding
assert_equal "ISO-8859-2", fixture_blob_memory("Data/README").ruby_encoding
assert_equal "UTF-8", sample_blob_memory("Text/foo.txt").encoding
assert_equal "UTF-8", sample_blob_memory("Text/foo.txt").ruby_encoding
assert_equal "UTF-16LE", fixture_blob_memory("Data/utf16le").encoding
assert_equal "UTF-16LE", fixture_blob_memory("Data/utf16le").ruby_encoding
assert_equal "UTF-16LE", fixture_blob_memory("Data/utf16le-windows").encoding
assert_equal "UTF-16LE", fixture_blob_memory("Data/utf16le-windows").ruby_encoding
assert_equal "ISO-2022-KR", sample_blob_memory("Text/ISO-2022-KR.txt").encoding
assert_equal "binary", sample_blob_memory("Text/ISO-2022-KR.txt").ruby_encoding
assert_nil fixture_blob_memory("Binary/dog.o").encoding
end
def test_binary
# Large blobs aren't loaded
large_blob = sample_blob("git.exe")
large_blob.instance_eval do
def data; end
end
assert large_blob.binary?
assert fixture_blob("Binary/git.deb").binary?
assert fixture_blob("Binary/git.exe").binary?
assert fixture_blob("Binary/hello.pbc").binary?
assert fixture_blob("Binary/linguist.gem").binary?
assert fixture_blob("Binary/octocat.ai").binary?
assert fixture_blob("Binary/octocat.png").binary?
assert fixture_blob("Binary/zip").binary?
assert !fixture_blob("Data/README").binary?
assert !sample_blob("Ruby/foo.rb").binary?
assert !sample_blob("Perl/script.pl").binary?
assert fixture_blob_memory("Binary/git.deb").binary?
assert fixture_blob_memory("Binary/hello.pbc").binary?
assert fixture_blob_memory("Binary/linguist.gem").binary?
assert fixture_blob_memory("Binary/octocat.ai").binary?
assert fixture_blob_memory("Binary/octocat.png").binary?
assert fixture_blob_memory("Binary/zip").binary?
assert !fixture_blob_memory("Data/README").binary?
assert !sample_blob_memory("Ruby/foo.rb").binary?
assert !sample_blob_memory("Perl/script.pl").binary?
end
def test_all_binary
Samples.each do |sample|
blob = sample_blob(sample[:path])
blob = sample_blob_memory(sample[:path])
assert ! (blob.likely_binary? || blob.binary?), "#{sample[:path]} is a binary file"
end
end
def test_text
assert fixture_blob("Data/README").text?
assert fixture_blob("Data/md").text?
assert sample_blob("Shell/script.sh").text?
assert fixture_blob("Data/txt").text?
assert fixture_blob_memory("Data/README").text?
assert fixture_blob_memory("Data/md").text?
assert sample_blob_memory("Shell/script.sh").text?
assert fixture_blob_memory("Data/txt").text?
end
def test_image
assert fixture_blob("Binary/octocat.gif").image?
assert fixture_blob("Binary/octocat.jpeg").image?
assert fixture_blob("Binary/octocat.jpg").image?
assert fixture_blob("Binary/octocat.png").image?
assert !fixture_blob("Binary/octocat.ai").image?
assert !fixture_blob("Binary/octocat.psd").image?
assert fixture_blob_memory("Binary/octocat.png").image?
assert !fixture_blob_memory("Binary/octocat.ai").image?
assert !fixture_blob_memory("Binary/octocat.psd").image?
end
def test_solid
assert fixture_blob("Binary/cube.stl").solid?
assert fixture_blob("Data/cube.stl").solid?
assert fixture_blob_memory("Binary/cube.stl").solid?
assert fixture_blob_memory("Data/cube.stl").solid?
end
def test_csv
assert fixture_blob("Data/cars.csv").csv?
assert fixture_blob_memory("Data/cars.csv").csv?
end
def test_pdf
assert fixture_blob("Binary/foo.pdf").pdf?
assert fixture_blob_memory("Binary/foo.pdf").pdf?
end
def test_viewable
assert fixture_blob("Data/README").viewable?
assert sample_blob("Ruby/foo.rb").viewable?
assert sample_blob("Perl/script.pl").viewable?
assert !fixture_blob("Binary/linguist.gem").viewable?
assert !fixture_blob("Binary/octocat.ai").viewable?
assert !fixture_blob("Binary/octocat.png").viewable?
assert fixture_blob_memory("Data/README").viewable?
assert sample_blob_memory("Ruby/foo.rb").viewable?
assert sample_blob_memory("Perl/script.pl").viewable?
assert !fixture_blob_memory("Binary/linguist.gem").viewable?
assert !fixture_blob_memory("Binary/octocat.ai").viewable?
assert !fixture_blob_memory("Binary/octocat.png").viewable?
end
def test_generated
assert !fixture_blob("Data/README").generated?
# Xcode project files
assert !sample_blob("XML/MainMenu.xib").generated?
assert fixture_blob("Binary/MainMenu.nib").generated?
assert !sample_blob("XML/project.pbxproj").generated?
# Gemfile.lock is NOT generated
assert !sample_blob("Gemfile.lock").generated?
assert !fixture_blob_memory("Data/README").generated?
# Generated .NET Docfiles
assert sample_blob("XML/net_docfile.xml").generated?
assert sample_blob_memory("XML/net_docfile.xml").generated?
# Long line
assert !sample_blob("JavaScript/uglify.js").generated?
assert !sample_blob_memory("JavaScript/uglify.js").generated?
# Inlined JS, but mostly code
assert !sample_blob("JavaScript/json2_backbone.js").generated?
assert !sample_blob_memory("JavaScript/json2_backbone.js").generated?
# Minified JS
assert !sample_blob("JavaScript/jquery-1.6.1.js").generated?
assert sample_blob("JavaScript/jquery-1.6.1.min.js").generated?
assert sample_blob("JavaScript/jquery-1.4.2.min.js").generated?
# CoffeeScript-generated JS
# TODO
# TypeScript-generated JS
# TODO
assert !sample_blob_memory("JavaScript/jquery-1.6.1.js").generated?
assert sample_blob_memory("JavaScript/jquery-1.6.1.min.js").generated?
assert sample_blob_memory("JavaScript/jquery-1.4.2.min.js").generated?
# Composer generated composer.lock file
assert sample_blob("JSON/composer.lock").generated?
assert sample_blob_memory("JSON/composer.lock").generated?
# PEG.js-generated parsers
assert sample_blob("JavaScript/parser.js").generated?
assert sample_blob_memory("JavaScript/parser.js").generated?
# Generated PostScript
assert !sample_blob("PostScript/sierpinski.ps").generated?
assert !sample_blob_memory("PostScript/sierpinski.ps").generated?
# These examples are too basic to tell
assert !sample_blob("JavaScript/hello.js").generated?
assert !sample_blob_memory("JavaScript/hello.js").generated?
assert sample_blob("JavaScript/intro-old.js").generated?
assert sample_blob("JavaScript/classes-old.js").generated?
assert sample_blob_memory("JavaScript/intro-old.js").generated?
assert sample_blob_memory("JavaScript/classes-old.js").generated?
assert sample_blob("JavaScript/intro.js").generated?
assert sample_blob("JavaScript/classes.js").generated?
assert sample_blob_memory("JavaScript/intro.js").generated?
assert sample_blob_memory("JavaScript/classes.js").generated?
# Protocol Buffer generated code
assert sample_blob("C++/protocol-buffer.pb.h").generated?
assert sample_blob("C++/protocol-buffer.pb.cc").generated?
assert sample_blob("Java/ProtocolBuffer.java").generated?
assert sample_blob("Python/protocol_buffer_pb2.py").generated?
assert sample_blob("Go/api.pb.go").generated?
assert sample_blob("Go/embedded.go").generated?
assert sample_blob_memory("C++/protocol-buffer.pb.h").generated?
assert sample_blob_memory("C++/protocol-buffer.pb.cc").generated?
assert sample_blob_memory("Java/ProtocolBuffer.java").generated?
assert sample_blob_memory("Python/protocol_buffer_pb2.py").generated?
assert sample_blob_memory("Go/api.pb.go").generated?
assert sample_blob_memory("Go/embedded.go").generated?
# Apache Thrift generated code
assert sample_blob("Python/gen-py-linguist-thrift.py").generated?
assert sample_blob("Go/gen-go-linguist-thrift.go").generated?
assert sample_blob("Java/gen-java-linguist-thrift.java").generated?
assert sample_blob("JavaScript/gen-js-linguist-thrift.js").generated?
assert sample_blob("Ruby/gen-rb-linguist-thrift.rb").generated?
assert sample_blob("Objective-C/gen-cocoa-linguist-thrift.m").generated?
assert sample_blob_memory("Python/gen-py-linguist-thrift.py").generated?
assert sample_blob_memory("Go/gen-go-linguist-thrift.go").generated?
assert sample_blob_memory("Java/gen-java-linguist-thrift.java").generated?
assert sample_blob_memory("JavaScript/gen-js-linguist-thrift.js").generated?
assert sample_blob_memory("Ruby/gen-rb-linguist-thrift.rb").generated?
assert sample_blob_memory("Objective-C/gen-cocoa-linguist-thrift.m").generated?
# Generated JNI
assert sample_blob("C/jni_layer.h").generated?
assert sample_blob_memory("C/jni_layer.h").generated?
# Minified CSS
assert !sample_blob("CSS/bootstrap.css").generated?
assert sample_blob("CSS/bootstrap.min.css").generated?
assert !sample_blob_memory("CSS/bootstrap.css").generated?
assert sample_blob_memory("CSS/bootstrap.min.css").generated?
# Generated VCR
assert sample_blob("YAML/vcr_cassette.yml").generated?
assert sample_blob_memory("YAML/vcr_cassette.yml").generated?
# Generated by Zephir
assert sample_blob("Zephir/filenames/exception.zep.c").generated?
assert sample_blob("Zephir/filenames/exception.zep.h").generated?
assert sample_blob("Zephir/filenames/exception.zep.php").generated?
assert !sample_blob("Zephir/Router.zep").generated?
assert sample_blob("node_modules/grunt/lib/grunt.js").generated?
# Godep saved dependencies
assert sample_blob("Godeps/Godeps.json").generated?
assert sample_blob("Godeps/_workspace/src/github.com/kr/s3/sign.go").generated?
assert !sample_blob_memory("Zephir/Router.zep").generated?
# Cython-generated C/C++
assert sample_blob("C/sgd_fast.c").generated?
assert sample_blob("C++/wrapper_inner.cpp").generated?
assert sample_blob_memory("C/sgd_fast.c").generated?
assert sample_blob_memory("C++/wrapper_inner.cpp").generated?
# Unity3D-generated metadata
assert sample_blob("Unity3D Asset/Tiles.meta").generated?
assert sample_blob_memory("Unity3D Asset/Tiles.meta").generated?
# Racc-generated Ruby
assert sample_blob_memory("Ruby/racc.rb").generated?
end
def test_vendored
assert !fixture_blob("Data/README").vendored?
assert !sample_blob("ext/extconf.rb").vendored?
# Dependencies
assert sample_blob("dependencies/windows/headers/GL/glext.h").vendored?
# Node dependencies
assert sample_blob("node_modules/coffee-script/lib/coffee-script.js").vendored?
# Bower Components
assert sample_blob("bower_components/custom/custom.js").vendored?
assert sample_blob("app/bower_components/custom/custom.js").vendored?
assert sample_blob("vendor/assets/bower_components/custom/custom.js").vendored?
# Go dependencies
assert !sample_blob("Godeps/Godeps.json").vendored?
assert sample_blob("Godeps/_workspace/src/github.com/kr/s3/sign.go").vendored?
# Rails vendor/
assert sample_blob("vendor/plugins/will_paginate/lib/will_paginate.rb").vendored?
# Vendor/
assert sample_blob("Vendor/my_great_file.h").vendored?
# 'thirdparty' directory
assert sample_blob("thirdparty/lib/main.c").vendored?
# 'extern(al)' directory
assert sample_blob("extern/util/__init__.py").vendored?
assert sample_blob("external/jquery.min.js").vendored?
# C deps
assert sample_blob("deps/http_parser/http_parser.c").vendored?
assert sample_blob("deps/v8/src/v8.h").vendored?
assert sample_blob("tools/something/else.c").vendored?
# Chart.js
assert sample_blob("some/vendored/path/Chart.js").vendored?
assert !sample_blob("some/vendored/path/chart.js").vendored?
# Codemirror deps
assert sample_blob("codemirror/mode/blah.js").vendored?
# Debian packaging
assert sample_blob("debian/cron.d").vendored?
# Erlang
assert sample_blob("rebar").vendored?
# git config files
assert_predicate fixture_blob("some/path/.gitattributes"), :vendored?
assert_predicate fixture_blob(".gitignore"), :vendored?
assert_predicate fixture_blob("special/path/.gitmodules"), :vendored?
# Minified JavaScript and CSS
assert sample_blob("foo.min.js").vendored?
assert sample_blob("foo.min.css").vendored?
assert sample_blob("foo-min.js").vendored?
assert sample_blob("foo-min.css").vendored?
assert !sample_blob("foomin.css").vendored?
assert !sample_blob("foo.min.txt").vendored?
#.osx
assert sample_blob(".osx").vendored?
# Prototype
assert !sample_blob("public/javascripts/application.js").vendored?
assert sample_blob("public/javascripts/prototype.js").vendored?
assert sample_blob("public/javascripts/effects.js").vendored?
assert sample_blob("public/javascripts/controls.js").vendored?
assert sample_blob("public/javascripts/dragdrop.js").vendored?
# jQuery
assert sample_blob("jquery.js").vendored?
assert sample_blob("public/javascripts/jquery.js").vendored?
assert sample_blob("public/javascripts/jquery.min.js").vendored?
assert sample_blob("public/javascripts/jquery-1.7.js").vendored?
assert sample_blob("public/javascripts/jquery-1.7.min.js").vendored?
assert sample_blob("public/javascripts/jquery-1.5.2.js").vendored?
assert sample_blob("public/javascripts/jquery-1.6.1.js").vendored?
assert sample_blob("public/javascripts/jquery-1.6.1.min.js").vendored?
assert sample_blob("public/javascripts/jquery-1.10.1.js").vendored?
assert sample_blob("public/javascripts/jquery-1.10.1.min.js").vendored?
assert !sample_blob("public/javascripts/jquery.github.menu.js").vendored?
# jQuery UI
assert sample_blob("themes/ui-lightness/jquery-ui.css").vendored?
assert sample_blob("themes/ui-lightness/jquery-ui-1.8.22.custom.css").vendored?
assert sample_blob("themes/ui-lightness/jquery.ui.accordion.css").vendored?
assert sample_blob("ui/i18n/jquery.ui.datepicker-ar.js").vendored?
assert sample_blob("ui/i18n/jquery-ui-i18n.js").vendored?
assert sample_blob("ui/jquery.effects.blind.js").vendored?
assert sample_blob("ui/jquery-ui-1.8.22.custom.js").vendored?
assert sample_blob("ui/jquery-ui-1.8.22.custom.min.js").vendored?
assert sample_blob("ui/jquery-ui-1.8.22.js").vendored?
assert sample_blob("ui/jquery-ui-1.8.js").vendored?
assert sample_blob("ui/jquery-ui.min.js").vendored?
assert sample_blob("ui/jquery.ui.accordion.js").vendored?
assert sample_blob("ui/minified/jquery.effects.blind.min.js").vendored?
assert sample_blob("ui/minified/jquery.ui.accordion.min.js").vendored?
# MooTools
assert sample_blob("public/javascripts/mootools-core-1.3.2-full-compat.js").vendored?
assert sample_blob("public/javascripts/mootools-core-1.3.2-full-compat-yc.js").vendored?
# Dojo
assert sample_blob("public/javascripts/dojo.js").vendored?
# MochiKit
assert sample_blob("public/javascripts/MochiKit.js").vendored?
# YUI
assert sample_blob("public/javascripts/yahoo-dom-event.js").vendored?
assert sample_blob("public/javascripts/yahoo-min.js").vendored?
assert sample_blob("public/javascripts/yuiloader-dom-event.js").vendored?
# WYS editors
assert sample_blob("public/javascripts/ckeditor.js").vendored?
assert sample_blob("public/javascripts/tiny_mce.js").vendored?
assert sample_blob("public/javascripts/tiny_mce_popup.js").vendored?
assert sample_blob("public/javascripts/tiny_mce_src.js").vendored?
# AngularJS
assert sample_blob("public/javascripts/angular.js").vendored?
assert sample_blob("public/javascripts/angular.min.js").vendored?
# D3.js
assert sample_blob("public/javascripts/d3.v3.js").vendored?
assert sample_blob("public/javascripts/d3.v3.min.js").vendored?
# Modernizr
assert sample_blob("public/javascripts/modernizr-2.7.1.js").vendored?
assert sample_blob("public/javascripts/modernizr.custom.01009.js").vendored?
# Fabric
assert sample_blob("fabfile.py").vendored?
# WAF
assert sample_blob("waf").vendored?
# Visual Studio IntelliSense
assert sample_blob("Scripts/jquery-1.7-vsdoc.js").vendored?
# Microsoft Ajax
assert sample_blob("Scripts/MicrosoftAjax.debug.js").vendored?
assert sample_blob("Scripts/MicrosoftAjax.js").vendored?
assert sample_blob("Scripts/MicrosoftMvcAjax.debug.js").vendored?
assert sample_blob("Scripts/MicrosoftMvcAjax.js").vendored?
assert sample_blob("Scripts/MicrosoftMvcValidation.debug.js").vendored?
assert sample_blob("Scripts/MicrosoftMvcValidation.js").vendored?
# jQuery validation plugin (MS bundles this with asp.net mvc)
assert sample_blob("Scripts/jquery.validate.js").vendored?
assert sample_blob("Scripts/jquery.validate.min.js").vendored?
assert sample_blob("Scripts/jquery.validate.unobtrusive.js").vendored?
assert sample_blob("Scripts/jquery.validate.unobtrusive.min.js").vendored?
assert sample_blob("Scripts/jquery.unobtrusive-ajax.js").vendored?
assert sample_blob("Scripts/jquery.unobtrusive-ajax.min.js").vendored?
# NuGet Packages
assert sample_blob("packages/Modernizr.2.0.6/Content/Scripts/modernizr-2.0.6-development-only.js").vendored?
# Font Awesome
assert sample_blob("some/asset/path/font-awesome.min.css").vendored?
assert sample_blob("some/asset/path/font-awesome.css").vendored?
# Normalize
assert sample_blob("some/asset/path/normalize.css").vendored?
# Carthage
assert sample_blob('Carthage/blah').vendored?
# Cocoapods
assert sample_blob('Pods/blah').vendored?
# Html5shiv
assert sample_blob("Scripts/html5shiv.js").vendored?
assert sample_blob("Scripts/html5shiv.min.js").vendored?
# Test fixtures
assert sample_blob("test/fixtures/random.rkt").vendored?
assert sample_blob("Test/fixtures/random.rkt").vendored?
assert sample_blob("tests/fixtures/random.rkt").vendored?
# Cordova/PhoneGap
assert sample_blob("cordova.js").vendored?
assert sample_blob("cordova.min.js").vendored?
assert sample_blob("cordova-2.1.0.js").vendored?
assert sample_blob("cordova-2.1.0.min.js").vendored?
# Foundation js
assert sample_blob("foundation.js").vendored?
assert sample_blob("foundation.min.js").vendored?
assert sample_blob("foundation.abide.js").vendored?
# Vagrant
assert sample_blob("Vagrantfile").vendored?
# Gradle
assert sample_blob("gradlew").vendored?
assert sample_blob("gradlew.bat").vendored?
assert sample_blob("gradle/wrapper/gradle-wrapper.properties").vendored?
assert sample_blob("subproject/gradlew").vendored?
assert sample_blob("subproject/gradlew.bat").vendored?
assert sample_blob("subproject/gradle/wrapper/gradle-wrapper.properties").vendored?
# Octicons
assert sample_blob("octicons.css").vendored?
assert sample_blob("public/octicons.min.css").vendored?
assert sample_blob("public/octicons/sprockets-octicons.scss").vendored?
# Typesafe Activator
assert sample_blob("activator").vendored?
assert sample_blob("activator.bat").vendored?
assert sample_blob("subproject/activator").vendored?
assert sample_blob("subproject/activator.bat").vendored?
assert_predicate fixture_blob(".google_apis/bar.jar"), :vendored?
assert_predicate fixture_blob("foo/.google_apis/bar.jar"), :vendored?
# Sphinx docs
assert sample_blob("docs/_build/asset.doc").vendored?
assert sample_blob("docs/theme/file.css").vendored?
# Vagrant
assert sample_blob("puphpet/file.pp").vendored?
# Fabric.io
assert sample_blob("Fabric.framework/Fabric.h").vendored?
# Crashlytics
assert sample_blob("Crashlytics.framework/Crashlytics.h").vendored?
end
def test_documentation
assert_predicate fixture_blob("doc/foo.html"), :documentation?
assert_predicate fixture_blob("docs/foo.html"), :documentation?
refute_predicate fixture_blob("project/doc/foo.html"), :documentation?
refute_predicate fixture_blob("project/docs/foo.html"), :documentation?
assert_predicate fixture_blob("Documentation/foo.md"), :documentation?
assert_predicate fixture_blob("documentation/foo.md"), :documentation?
assert_predicate fixture_blob("project/Documentation/foo.md"), :documentation?
assert_predicate fixture_blob("project/documentation/foo.md"), :documentation?
assert_predicate fixture_blob("javadoc/foo.html"), :documentation?
assert_predicate fixture_blob("project/javadoc/foo.html"), :documentation?
assert_predicate fixture_blob("man/foo.html"), :documentation?
refute_predicate fixture_blob("project/man/foo.html"), :documentation?
assert_predicate fixture_blob("README"), :documentation?
assert_predicate fixture_blob("README.md"), :documentation?
assert_predicate fixture_blob("README.txt"), :documentation?
assert_predicate fixture_blob("Readme"), :documentation?
assert_predicate fixture_blob("readme"), :documentation?
assert_predicate fixture_blob("foo/README"), :documentation?
assert_predicate fixture_blob("CHANGE"), :documentation?
assert_predicate fixture_blob("CHANGE.md"), :documentation?
assert_predicate fixture_blob("CHANGE.txt"), :documentation?
assert_predicate fixture_blob("foo/CHANGE"), :documentation?
assert_predicate fixture_blob("CHANGELOG"), :documentation?
assert_predicate fixture_blob("CHANGELOG.md"), :documentation?
assert_predicate fixture_blob("CHANGELOG.txt"), :documentation?
assert_predicate fixture_blob("foo/CHANGELOG"), :documentation?
assert_predicate fixture_blob("CHANGES"), :documentation?
assert_predicate fixture_blob("CHANGES.md"), :documentation?
assert_predicate fixture_blob("CHANGES.txt"), :documentation?
assert_predicate fixture_blob("foo/CHANGES"), :documentation?
assert_predicate fixture_blob("CONTRIBUTING"), :documentation?
assert_predicate fixture_blob("CONTRIBUTING.md"), :documentation?
assert_predicate fixture_blob("CONTRIBUTING.txt"), :documentation?
assert_predicate fixture_blob("foo/CONTRIBUTING"), :documentation?
assert_predicate fixture_blob("examples/some-file.pl"), :documentation?
assert_predicate fixture_blob("Examples/some-example-file.rb"), :documentation?
assert_predicate fixture_blob("LICENSE"), :documentation?
assert_predicate fixture_blob("LICENCE.md"), :documentation?
assert_predicate fixture_blob("License.txt"), :documentation?
assert_predicate fixture_blob("LICENSE.txt"), :documentation?
assert_predicate fixture_blob("foo/LICENSE"), :documentation?
assert_predicate fixture_blob("COPYING"), :documentation?
assert_predicate fixture_blob("COPYING.md"), :documentation?
assert_predicate fixture_blob("COPYING.txt"), :documentation?
assert_predicate fixture_blob("foo/COPYING"), :documentation?
assert_predicate fixture_blob("INSTALL"), :documentation?
assert_predicate fixture_blob("INSTALL.md"), :documentation?
assert_predicate fixture_blob("INSTALL.txt"), :documentation?
assert_predicate fixture_blob("foo/INSTALL"), :documentation?
refute_predicate fixture_blob("foo.md"), :documentation?
# Samples
assert sample_blob("Samples/Ruby/foo.rb").documentation?
assert_predicate fixture_blob("INSTALL.txt"), :documentation?
assert !fixture_blob_memory("Data/README").vendored?
end
def test_language
Samples.each do |sample|
blob = sample_blob(sample[:path])
blob = sample_blob_memory(sample[:path])
assert blob.language, "No language for #{sample[:path]}"
assert_equal sample[:language], blob.language.name, blob.name
end
@@ -586,7 +248,7 @@ class TestBlob < Minitest::Test
filepath = File.join(dirname, filename)
next unless File.file?(filepath)
blob = fixture_blob(filepath)
blob = fixture_blob_memory(filepath)
if language == 'Data'
assert blob.language.nil?, "A language was found for #{filepath}"
elsif language == 'Generated'
@@ -600,7 +262,7 @@ class TestBlob < Minitest::Test
end
def test_minified_files_not_safe_to_highlight
assert !sample_blob("JavaScript/jquery-1.6.1.min.js").safe_to_colorize?
assert !sample_blob_memory("JavaScript/jquery-1.6.1.min.js").safe_to_colorize?
end
def test_empty
@@ -613,27 +275,19 @@ class TestBlob < Minitest::Test
end
def test_include_in_language_stats
vendored = sample_blob("bower_components/custom/custom.js")
assert_predicate vendored, :vendored?
refute_predicate vendored, :include_in_language_stats?
documentation = fixture_blob("README")
assert_predicate documentation, :documentation?
refute_predicate documentation, :include_in_language_stats?
generated = sample_blob("CSS/bootstrap.min.css")
generated = sample_blob_memory("CSS/bootstrap.min.css")
assert_predicate generated, :generated?
refute_predicate generated, :include_in_language_stats?
data = sample_blob("Ant Build System/filenames/ant.xml")
data = sample_blob_memory("Ant Build System/filenames/ant.xml")
assert_equal :data, data.language.type
refute_predicate data, :include_in_language_stats?
prose = sample_blob("Markdown/tender.md")
prose = sample_blob_memory("Markdown/tender.md")
assert_equal :prose, prose.language.type
refute_predicate prose, :include_in_language_stats?
included = sample_blob("HTML/pages.html")
included = sample_blob_memory("HTML/pages.html")
assert_predicate included, :include_in_language_stats?
end
end

View File

@@ -1,9 +1,669 @@
require_relative "./helper"
class TestFileBlob < Minitest::Test
class TestBlob < Minitest::Test
include Linguist
def setup
# git blobs are normally loaded as ASCII-8BIT since they may contain data
# with arbitrary encoding not known ahead of time
@original_external = Encoding.default_external
Encoding.default_external = Encoding.find("ASCII-8BIT")
end
def teardown
Encoding.default_external = @original_external
end
def script_blob(name)
blob = sample_blob(name)
blob.instance_variable_set(:@name, 'script')
blob
end
def test_extensions
assert_equal [".gitignore"], Linguist::FileBlob.new(".gitignore").extensions
assert_equal [".xml"], Linguist::FileBlob.new("build.xml").extensions
assert_equal [".html.erb", ".erb"], Linguist::FileBlob.new("dotted.dir/index.html.erb").extensions
end
def test_name
assert_equal "foo.rb", sample_blob("foo.rb").name
end
def test_mime_type
assert_equal "application/postscript", fixture_blob("Binary/octocat.ai").mime_type
assert_equal "application/x-ruby", sample_blob("Ruby/grit.rb").mime_type
assert_equal "application/x-sh", sample_blob("Shell/script.sh").mime_type
assert_equal "application/xml", sample_blob("XML/bar.xml").mime_type
assert_equal "audio/ogg", fixture_blob("Binary/foo.ogg").mime_type
assert_equal "text/plain", fixture_blob("Data/README").mime_type
end
def test_content_type
assert_equal "application/pdf", fixture_blob("Binary/foo.pdf").content_type
assert_equal "audio/ogg", fixture_blob("Binary/foo.ogg").content_type
assert_equal "image/png", fixture_blob("Binary/foo.png").content_type
assert_equal "text/plain; charset=iso-8859-2", fixture_blob("Data/README").content_type
end
def test_disposition
assert_equal "attachment; filename=foo+bar.jar", fixture_blob("Binary/foo bar.jar").disposition
assert_equal "attachment; filename=foo.bin", fixture_blob("Binary/foo.bin").disposition
assert_equal "attachment; filename=linguist.gem", fixture_blob("Binary/linguist.gem").disposition
assert_equal "attachment; filename=octocat.ai", fixture_blob("Binary/octocat.ai").disposition
assert_equal "inline", fixture_blob("Data/README").disposition
assert_equal "inline", sample_blob("Text/foo.txt").disposition
assert_equal "inline", sample_blob("Ruby/grit.rb").disposition
assert_equal "inline", fixture_blob("Binary/octocat.png").disposition
end
def test_data
assert_equal "module Foo\nend\n", sample_blob("Ruby/foo.rb").data
end
def test_lines
assert_equal ["module Foo", "end", ""], sample_blob("Ruby/foo.rb").lines
assert_equal ["line 1", "line 2", ""], sample_blob("Text/mac.txt").lines
assert_equal 475, sample_blob("Emacs Lisp/ess-julia.el").lines.length
end
def test_lines_maintains_original_encoding
# Even if the file's encoding is detected as something like UTF-16LE,
# earlier versions of the gem made implicit guarantees that the encoding of
# each `line` is in the same encoding as the file was originally read (in
# practice, UTF-8 or ASCII-8BIT)
assert_equal Encoding.default_external, fixture_blob("Data/utf16le").lines.first.encoding
end
def test_size
assert_equal 15, sample_blob("Ruby/foo.rb").size
end
def test_loc
assert_equal 3, sample_blob("Ruby/foo.rb").loc
end
def test_sloc
assert_equal 2, sample_blob("Ruby/foo.rb").sloc
assert_equal 3, fixture_blob("Data/utf16le-windows").sloc
assert_equal 1, fixture_blob("Data/iso8859-8-i").sloc
end
def test_encoding
assert_equal "ISO-8859-2", fixture_blob("Data/README").encoding
assert_equal "ISO-8859-2", fixture_blob("Data/README").ruby_encoding
assert_equal "UTF-8", sample_blob("Text/foo.txt").encoding
assert_equal "UTF-8", sample_blob("Text/foo.txt").ruby_encoding
assert_equal "UTF-16LE", fixture_blob("Data/utf16le").encoding
assert_equal "UTF-16LE", fixture_blob("Data/utf16le").ruby_encoding
assert_equal "UTF-16LE", fixture_blob("Data/utf16le-windows").encoding
assert_equal "UTF-16LE", fixture_blob("Data/utf16le-windows").ruby_encoding
assert_equal "ISO-2022-KR", sample_blob("Text/ISO-2022-KR.txt").encoding
assert_equal "binary", sample_blob("Text/ISO-2022-KR.txt").ruby_encoding
assert_nil fixture_blob("Binary/dog.o").encoding
end
def test_binary
# Large blobs aren't loaded
large_blob = sample_blob("git.exe")
large_blob.instance_eval do
def data; end
end
assert large_blob.binary?
assert fixture_blob("Binary/git.deb").binary?
assert fixture_blob("Binary/git.exe").binary?
assert fixture_blob("Binary/hello.pbc").binary?
assert fixture_blob("Binary/linguist.gem").binary?
assert fixture_blob("Binary/octocat.ai").binary?
assert fixture_blob("Binary/octocat.png").binary?
assert fixture_blob("Binary/zip").binary?
assert !fixture_blob("Data/README").binary?
assert !sample_blob("Ruby/foo.rb").binary?
assert !sample_blob("Perl/script.pl").binary?
end
def test_all_binary
Samples.each do |sample|
blob = sample_blob(sample[:path])
assert ! (blob.likely_binary? || blob.binary?), "#{sample[:path]} is a binary file"
end
end
def test_text
assert fixture_blob("Data/README").text?
assert fixture_blob("Data/md").text?
assert sample_blob("Shell/script.sh").text?
assert fixture_blob("Data/txt").text?
end
def test_image
assert fixture_blob("Binary/octocat.gif").image?
assert fixture_blob("Binary/octocat.jpeg").image?
assert fixture_blob("Binary/octocat.jpg").image?
assert fixture_blob("Binary/octocat.png").image?
assert !fixture_blob("Binary/octocat.ai").image?
assert !fixture_blob("Binary/octocat.psd").image?
end
def test_solid
assert fixture_blob("Binary/cube.stl").solid?
assert fixture_blob("Data/cube.stl").solid?
end
def test_csv
assert fixture_blob("Data/cars.csv").csv?
end
def test_pdf
assert fixture_blob("Binary/foo.pdf").pdf?
end
def test_viewable
assert fixture_blob("Data/README").viewable?
assert sample_blob("Ruby/foo.rb").viewable?
assert sample_blob("Perl/script.pl").viewable?
assert !fixture_blob("Binary/linguist.gem").viewable?
assert !fixture_blob("Binary/octocat.ai").viewable?
assert !fixture_blob("Binary/octocat.png").viewable?
end
def test_generated
assert !fixture_blob("Data/README").generated?
# Xcode project files
assert !sample_blob("XML/MainMenu.xib").generated?
assert fixture_blob("Binary/MainMenu.nib").generated?
assert !sample_blob("XML/project.pbxproj").generated?
# Gemfile.lock is NOT generated
assert !sample_blob("Gemfile.lock").generated?
# Generated .NET Docfiles
assert sample_blob("XML/net_docfile.xml").generated?
# Long line
assert !sample_blob("JavaScript/uglify.js").generated?
# Inlined JS, but mostly code
assert !sample_blob("JavaScript/json2_backbone.js").generated?
# Minified JS
assert !sample_blob("JavaScript/jquery-1.6.1.js").generated?
assert sample_blob("JavaScript/jquery-1.6.1.min.js").generated?
assert sample_blob("JavaScript/jquery-1.4.2.min.js").generated?
# CoffeeScript-generated JS
# TODO
# TypeScript-generated JS
# TODO
# Composer generated composer.lock file
assert sample_blob("JSON/composer.lock").generated?
# PEG.js-generated parsers
assert sample_blob("JavaScript/parser.js").generated?
# Generated PostScript
assert !sample_blob("PostScript/sierpinski.ps").generated?
# These examples are too basic to tell
assert !sample_blob("JavaScript/hello.js").generated?
assert sample_blob("JavaScript/intro-old.js").generated?
assert sample_blob("JavaScript/classes-old.js").generated?
assert sample_blob("JavaScript/intro.js").generated?
assert sample_blob("JavaScript/classes.js").generated?
# Protocol Buffer generated code
assert sample_blob("C++/protocol-buffer.pb.h").generated?
assert sample_blob("C++/protocol-buffer.pb.cc").generated?
assert sample_blob("Java/ProtocolBuffer.java").generated?
assert sample_blob("Python/protocol_buffer_pb2.py").generated?
assert sample_blob("Go/api.pb.go").generated?
assert sample_blob("Go/embedded.go").generated?
# Apache Thrift generated code
assert sample_blob("Python/gen-py-linguist-thrift.py").generated?
assert sample_blob("Go/gen-go-linguist-thrift.go").generated?
assert sample_blob("Java/gen-java-linguist-thrift.java").generated?
assert sample_blob("JavaScript/gen-js-linguist-thrift.js").generated?
assert sample_blob("Ruby/gen-rb-linguist-thrift.rb").generated?
assert sample_blob("Objective-C/gen-cocoa-linguist-thrift.m").generated?
# Generated JNI
assert sample_blob("C/jni_layer.h").generated?
# Minified CSS
assert !sample_blob("CSS/bootstrap.css").generated?
assert sample_blob("CSS/bootstrap.min.css").generated?
# Generated VCR
assert sample_blob("YAML/vcr_cassette.yml").generated?
# Generated by Zephir
assert sample_blob("Zephir/filenames/exception.zep.c").generated?
assert sample_blob("Zephir/filenames/exception.zep.h").generated?
assert sample_blob("Zephir/filenames/exception.zep.php").generated?
assert !sample_blob("Zephir/Router.zep").generated?
assert sample_blob("node_modules/grunt/lib/grunt.js").generated?
# Godep saved dependencies
assert sample_blob("Godeps/Godeps.json").generated?
assert sample_blob("Godeps/_workspace/src/github.com/kr/s3/sign.go").generated?
# Cython-generated C/C++
assert sample_blob("C/sgd_fast.c").generated?
assert sample_blob("C++/wrapper_inner.cpp").generated?
# Unity3D-generated metadata
assert sample_blob("Unity3D Asset/Tiles.meta").generated?
end
def test_vendored
assert !fixture_blob("Data/README").vendored?
assert !sample_blob("ext/extconf.rb").vendored?
# Dependencies
assert sample_blob("dependencies/windows/headers/GL/glext.h").vendored?
# Node dependencies
assert sample_blob("node_modules/coffee-script/lib/coffee-script.js").vendored?
# Bower Components
assert sample_blob("bower_components/custom/custom.js").vendored?
assert sample_blob("app/bower_components/custom/custom.js").vendored?
assert sample_blob("vendor/assets/bower_components/custom/custom.js").vendored?
# Go dependencies
assert !sample_blob("Godeps/Godeps.json").vendored?
assert sample_blob("Godeps/_workspace/src/github.com/kr/s3/sign.go").vendored?
# Rails vendor/
assert sample_blob("vendor/plugins/will_paginate/lib/will_paginate.rb").vendored?
# Vendor/
assert sample_blob("Vendor/my_great_file.h").vendored?
# 'thirdparty' directory
assert sample_blob("thirdparty/lib/main.c").vendored?
# 'extern(al)' directory
assert sample_blob("extern/util/__init__.py").vendored?
assert sample_blob("external/jquery.min.js").vendored?
# C deps
assert sample_blob("deps/http_parser/http_parser.c").vendored?
assert sample_blob("deps/v8/src/v8.h").vendored?
assert sample_blob("tools/something/else.c").vendored?
# Chart.js
assert sample_blob("some/vendored/path/Chart.js").vendored?
assert !sample_blob("some/vendored/path/chart.js").vendored?
# Codemirror deps
assert sample_blob("codemirror/mode/blah.js").vendored?
assert sample_blob("codemirror/5.0/mode/blah.js").vendored?
# Debian packaging
assert sample_blob("debian/cron.d").vendored?
# Erlang
assert sample_blob("rebar").vendored?
# git config files
assert_predicate fixture_blob("some/path/.gitattributes"), :vendored?
assert_predicate fixture_blob(".gitignore"), :vendored?
assert_predicate fixture_blob("special/path/.gitmodules"), :vendored?
# Minified JavaScript and CSS
assert sample_blob("foo.min.js").vendored?
assert sample_blob("foo.min.css").vendored?
assert sample_blob("foo-min.js").vendored?
assert sample_blob("foo-min.css").vendored?
assert !sample_blob("foomin.css").vendored?
assert !sample_blob("foo.min.txt").vendored?
#.osx
assert sample_blob(".osx").vendored?
# Prototype
assert !sample_blob("public/javascripts/application.js").vendored?
assert sample_blob("public/javascripts/prototype.js").vendored?
assert sample_blob("public/javascripts/effects.js").vendored?
assert sample_blob("public/javascripts/controls.js").vendored?
assert sample_blob("public/javascripts/dragdrop.js").vendored?
# jQuery
assert sample_blob("jquery.js").vendored?
assert sample_blob("public/javascripts/jquery.js").vendored?
assert sample_blob("public/javascripts/jquery.min.js").vendored?
assert sample_blob("public/javascripts/jquery-1.7.js").vendored?
assert sample_blob("public/javascripts/jquery-1.7.min.js").vendored?
assert sample_blob("public/javascripts/jquery-1.5.2.js").vendored?
assert sample_blob("public/javascripts/jquery-1.6.1.js").vendored?
assert sample_blob("public/javascripts/jquery-1.6.1.min.js").vendored?
assert sample_blob("public/javascripts/jquery-1.10.1.js").vendored?
assert sample_blob("public/javascripts/jquery-1.10.1.min.js").vendored?
assert !sample_blob("public/javascripts/jquery.github.menu.js").vendored?
# jQuery UI
assert sample_blob("themes/ui-lightness/jquery-ui.css").vendored?
assert sample_blob("themes/ui-lightness/jquery-ui-1.8.22.custom.css").vendored?
assert sample_blob("themes/ui-lightness/jquery.ui.accordion.css").vendored?
assert sample_blob("ui/i18n/jquery.ui.datepicker-ar.js").vendored?
assert sample_blob("ui/i18n/jquery-ui-i18n.js").vendored?
assert sample_blob("ui/jquery.effects.blind.js").vendored?
assert sample_blob("ui/jquery-ui-1.8.22.custom.js").vendored?
assert sample_blob("ui/jquery-ui-1.8.22.custom.min.js").vendored?
assert sample_blob("ui/jquery-ui-1.8.22.js").vendored?
assert sample_blob("ui/jquery-ui-1.8.js").vendored?
assert sample_blob("ui/jquery-ui.min.js").vendored?
assert sample_blob("ui/jquery.ui.accordion.js").vendored?
assert sample_blob("ui/minified/jquery.effects.blind.min.js").vendored?
assert sample_blob("ui/minified/jquery.ui.accordion.min.js").vendored?
# jQuery Gantt
assert sample_blob("web-app/jquery-gantt/js/jquery.fn.gantt.js").vendored?
# jQuery fancyBox
assert sample_blob("web-app/fancybox/jquery.fancybox.js").vendored?
# Fuel UX
assert sample_blob("web-app/fuelux/js/fuelux.js").vendored?
# jQuery File Upload
assert sample_blob("fileupload-9.0.0/jquery.fileupload-process.js").vendored?
# Slick
assert sample_blob("web-app/slickgrid/controls/slick.columnpicker.js").vendored?
# Leaflet plugins
assert sample_blob("leaflet-plugins/Leaflet.Coordinates-0.5.0.src.js").vendored?
assert sample_blob("leaflet-plugins/leaflet.draw-src.js").vendored?
assert sample_blob("leaflet-plugins/leaflet.spin.js").vendored?
# MooTools
assert sample_blob("public/javascripts/mootools-core-1.3.2-full-compat.js").vendored?
assert sample_blob("public/javascripts/mootools-core-1.3.2-full-compat-yc.js").vendored?
# Dojo
assert sample_blob("public/javascripts/dojo.js").vendored?
# MochiKit
assert sample_blob("public/javascripts/MochiKit.js").vendored?
# YUI
assert sample_blob("public/javascripts/yahoo-dom-event.js").vendored?
assert sample_blob("public/javascripts/yahoo-min.js").vendored?
assert sample_blob("public/javascripts/yuiloader-dom-event.js").vendored?
# WYS editors
assert sample_blob("public/javascripts/ckeditor.js").vendored?
assert sample_blob("public/javascripts/tiny_mce.js").vendored?
assert sample_blob("public/javascripts/tiny_mce_popup.js").vendored?
assert sample_blob("public/javascripts/tiny_mce_src.js").vendored?
# AngularJS
assert sample_blob("public/javascripts/angular.js").vendored?
assert sample_blob("public/javascripts/angular.min.js").vendored?
# D3.js
assert sample_blob("public/javascripts/d3.v3.js").vendored?
assert sample_blob("public/javascripts/d3.v3.min.js").vendored?
# Modernizr
assert sample_blob("public/javascripts/modernizr-2.7.1.js").vendored?
assert sample_blob("public/javascripts/modernizr.custom.01009.js").vendored?
# Fabric
assert sample_blob("fabfile.py").vendored?
# WAF
assert sample_blob("waf").vendored?
# Visual Studio IntelliSense
assert sample_blob("Scripts/jquery-1.7-vsdoc.js").vendored?
# Microsoft Ajax
assert sample_blob("Scripts/MicrosoftAjax.debug.js").vendored?
assert sample_blob("Scripts/MicrosoftAjax.js").vendored?
assert sample_blob("Scripts/MicrosoftMvcAjax.debug.js").vendored?
assert sample_blob("Scripts/MicrosoftMvcAjax.js").vendored?
assert sample_blob("Scripts/MicrosoftMvcValidation.debug.js").vendored?
assert sample_blob("Scripts/MicrosoftMvcValidation.js").vendored?
# jQuery validation plugin (MS bundles this with asp.net mvc)
assert sample_blob("Scripts/jquery.validate.js").vendored?
assert sample_blob("Scripts/jquery.validate.min.js").vendored?
assert sample_blob("Scripts/jquery.validate.unobtrusive.js").vendored?
assert sample_blob("Scripts/jquery.validate.unobtrusive.min.js").vendored?
assert sample_blob("Scripts/jquery.unobtrusive-ajax.js").vendored?
assert sample_blob("Scripts/jquery.unobtrusive-ajax.min.js").vendored?
# NuGet Packages
assert sample_blob("packages/Modernizr.2.0.6/Content/Scripts/modernizr-2.0.6-development-only.js").vendored?
# Font Awesome
assert sample_blob("some/asset/path/font-awesome.min.css").vendored?
assert sample_blob("some/asset/path/font-awesome.css").vendored?
# Normalize
assert sample_blob("some/asset/path/normalize.css").vendored?
# Carthage
assert sample_blob('Carthage/blah').vendored?
# Cocoapods
assert sample_blob('Pods/blah').vendored?
# Html5shiv
assert sample_blob("Scripts/html5shiv.js").vendored?
assert sample_blob("Scripts/html5shiv.min.js").vendored?
# Test fixtures
assert sample_blob("test/fixtures/random.rkt").vendored?
assert sample_blob("Test/fixtures/random.rkt").vendored?
assert sample_blob("tests/fixtures/random.rkt").vendored?
# Cordova/PhoneGap
assert sample_blob("cordova.js").vendored?
assert sample_blob("cordova.min.js").vendored?
assert sample_blob("cordova-2.1.0.js").vendored?
assert sample_blob("cordova-2.1.0.min.js").vendored?
# Foundation js
assert sample_blob("foundation.js").vendored?
assert sample_blob("foundation.min.js").vendored?
assert sample_blob("foundation.abide.js").vendored?
# Vagrant
assert sample_blob("Vagrantfile").vendored?
# Gradle
assert sample_blob("gradlew").vendored?
assert sample_blob("gradlew.bat").vendored?
assert sample_blob("gradle/wrapper/gradle-wrapper.properties").vendored?
assert sample_blob("subproject/gradlew").vendored?
assert sample_blob("subproject/gradlew.bat").vendored?
assert sample_blob("subproject/gradle/wrapper/gradle-wrapper.properties").vendored?
# Octicons
assert sample_blob("octicons.css").vendored?
assert sample_blob("public/octicons.min.css").vendored?
assert sample_blob("public/octicons/sprockets-octicons.scss").vendored?
# Typesafe Activator
assert sample_blob("activator").vendored?
assert sample_blob("activator.bat").vendored?
assert sample_blob("subproject/activator").vendored?
assert sample_blob("subproject/activator.bat").vendored?
assert_predicate fixture_blob(".google_apis/bar.jar"), :vendored?
assert_predicate fixture_blob("foo/.google_apis/bar.jar"), :vendored?
# Sphinx docs
assert sample_blob("docs/_build/asset.doc").vendored?
assert sample_blob("docs/theme/file.css").vendored?
# Vagrant
assert sample_blob("puphpet/file.pp").vendored?
# Fabric.io
assert sample_blob("Fabric.framework/Fabric.h").vendored?
# Crashlytics
assert sample_blob("Crashlytics.framework/Crashlytics.h").vendored?
assert sample_blob("myapp/My Template.xctemplate/___FILEBASENAME___.h").vendored?
assert sample_blob("myapp/My Images.xcassets/some/stuff.imageset/Contents.json").vendored?
assert !sample_blob("myapp/MyData.json").vendored?
end
def test_documentation
assert_predicate fixture_blob("doc/foo.html"), :documentation?
assert_predicate fixture_blob("docs/foo.html"), :documentation?
refute_predicate fixture_blob("project/doc/foo.html"), :documentation?
refute_predicate fixture_blob("project/docs/foo.html"), :documentation?
assert_predicate fixture_blob("Documentation/foo.md"), :documentation?
assert_predicate fixture_blob("documentation/foo.md"), :documentation?
assert_predicate fixture_blob("project/Documentation/foo.md"), :documentation?
assert_predicate fixture_blob("project/documentation/foo.md"), :documentation?
assert_predicate fixture_blob("javadoc/foo.html"), :documentation?
assert_predicate fixture_blob("project/javadoc/foo.html"), :documentation?
assert_predicate fixture_blob("man/foo.html"), :documentation?
refute_predicate fixture_blob("project/man/foo.html"), :documentation?
assert_predicate fixture_blob("README"), :documentation?
assert_predicate fixture_blob("README.md"), :documentation?
assert_predicate fixture_blob("README.txt"), :documentation?
assert_predicate fixture_blob("Readme"), :documentation?
assert_predicate fixture_blob("readme"), :documentation?
assert_predicate fixture_blob("foo/README"), :documentation?
assert_predicate fixture_blob("CHANGE"), :documentation?
assert_predicate fixture_blob("CHANGE.md"), :documentation?
assert_predicate fixture_blob("CHANGE.txt"), :documentation?
assert_predicate fixture_blob("foo/CHANGE"), :documentation?
assert_predicate fixture_blob("CHANGELOG"), :documentation?
assert_predicate fixture_blob("CHANGELOG.md"), :documentation?
assert_predicate fixture_blob("CHANGELOG.txt"), :documentation?
assert_predicate fixture_blob("foo/CHANGELOG"), :documentation?
assert_predicate fixture_blob("CHANGES"), :documentation?
assert_predicate fixture_blob("CHANGES.md"), :documentation?
assert_predicate fixture_blob("CHANGES.txt"), :documentation?
assert_predicate fixture_blob("foo/CHANGES"), :documentation?
assert_predicate fixture_blob("CONTRIBUTING"), :documentation?
assert_predicate fixture_blob("CONTRIBUTING.md"), :documentation?
assert_predicate fixture_blob("CONTRIBUTING.txt"), :documentation?
assert_predicate fixture_blob("foo/CONTRIBUTING"), :documentation?
assert_predicate fixture_blob("examples/some-file.pl"), :documentation?
assert_predicate fixture_blob("Examples/some-example-file.rb"), :documentation?
assert_predicate fixture_blob("LICENSE"), :documentation?
assert_predicate fixture_blob("LICENCE.md"), :documentation?
assert_predicate fixture_blob("License.txt"), :documentation?
assert_predicate fixture_blob("LICENSE.txt"), :documentation?
assert_predicate fixture_blob("foo/LICENSE"), :documentation?
assert_predicate fixture_blob("COPYING"), :documentation?
assert_predicate fixture_blob("COPYING.md"), :documentation?
assert_predicate fixture_blob("COPYING.txt"), :documentation?
assert_predicate fixture_blob("foo/COPYING"), :documentation?
assert_predicate fixture_blob("INSTALL"), :documentation?
assert_predicate fixture_blob("INSTALL.md"), :documentation?
assert_predicate fixture_blob("INSTALL.txt"), :documentation?
assert_predicate fixture_blob("foo/INSTALL"), :documentation?
refute_predicate fixture_blob("foo.md"), :documentation?
# Samples
assert sample_blob("Samples/Ruby/foo.rb").documentation?
assert_predicate fixture_blob("INSTALL.txt"), :documentation?
end
def test_language
Samples.each do |sample|
blob = sample_blob(sample[:path])
assert blob.language, "No language for #{sample[:path]}"
assert_equal sample[:language], blob.language.name, blob.name
end
# Test language detection for files which shouldn't be used as samples
root = File.expand_path('../fixtures', __FILE__)
Dir.entries(root).each do |language|
next if language == '.' || language == '..' || language == 'Binary' ||
File.basename(language) == 'ace_modes.json'
# Each directory contains test files of a language
dirname = File.join(root, language)
Dir.entries(dirname).each do |filename|
# By default blob search the file in the samples;
# thus, we need to give it the absolute path
filepath = File.join(dirname, filename)
next unless File.file?(filepath)
blob = fixture_blob(filepath)
if language == 'Data'
assert blob.language.nil?, "A language was found for #{filepath}"
elsif language == 'Generated'
assert blob.generated?, "#{filepath} is not a generated file"
else
assert blob.language, "No language for #{filepath}"
assert_equal language, blob.language.name, blob.name
end
end
end
end
def test_minified_files_not_safe_to_highlight
assert !sample_blob("JavaScript/jquery-1.6.1.min.js").safe_to_colorize?
end
def test_empty
blob = Struct.new(:data) { include Linguist::BlobHelper }
assert blob.new("").empty?
assert blob.new(nil).empty?
refute blob.new(" ").empty?
refute blob.new("nope").empty?
end
def test_include_in_language_stats
vendored = sample_blob("bower_components/custom/custom.js")
assert_predicate vendored, :vendored?
refute_predicate vendored, :include_in_language_stats?
documentation = fixture_blob("README")
assert_predicate documentation, :documentation?
refute_predicate documentation, :include_in_language_stats?
generated = sample_blob("CSS/bootstrap.min.css")
assert_predicate generated, :generated?
refute_predicate generated, :include_in_language_stats?
data = sample_blob("Ant Build System/filenames/ant.xml")
assert_equal :data, data.language.type
refute_predicate data, :include_in_language_stats?
prose = sample_blob("Markdown/tender.md")
assert_equal :prose, prose.language.type
refute_predicate prose, :include_in_language_stats?
included = sample_blob("HTML/pages.html")
assert_predicate included, :include_in_language_stats?
end
end

View File

@@ -3,7 +3,7 @@ require_relative "./helper"
class TestGrammars < Minitest::Test
ROOT = File.expand_path("../..", __FILE__)
LICENSE_WHITELIST = [
PROJECT_WHITELIST = [
# This grammar's MIT license is inside a subdirectory.
"vendor/grammars/SublimePapyrus",
@@ -16,6 +16,23 @@ class TestGrammars < Minitest::Test
"vendor/grammars/x86-assembly-textmate-bundle"
].freeze
# List of allowed SPDX license names
LICENSE_WHITELIST = %w[
apache-2.0
bsd-2-clause
bsd-3-clause
cc-by-sa-3.0
gpl-2.0
gpl-3.0
lgpl-3.0
mit
mpl-2.0
textmate
unlicense
wtfpl
zlib
].freeze
def setup
@grammars = YAML.load(File.read(File.join(ROOT, "grammars.yml")))
end
@@ -62,48 +79,38 @@ class TestGrammars < Minitest::Test
end
end
def test_submodules_have_recognized_licenses
unrecognized = submodule_licenses.select { |k,v| v.nil? && Licensee::FSProject.new(k).license_file }
unrecognized.reject! { |k,v| PROJECT_WHITELIST.include?(k) }
message = "The following submodules have unrecognized licenses:\n* #{unrecognized.keys.join("\n* ")}\n"
message << "Please ensure that the project's LICENSE file contains the full text of the license."
assert_equal Hash.new, unrecognized, message
end
def test_submodules_have_licenses
categories = submodule_paths.group_by do |submodule|
files = Dir[File.join(ROOT, submodule, "*")]
license = files.find { |path| File.basename(path) =~ /\b(un)?licen[cs]e\b/i } || files.find { |path| File.basename(path) =~ /\bcopying\b/i }
if license.nil?
if readme = files.find { |path| File.basename(path) =~ /\Areadme\b/i }
license = readme if File.read(readme) =~ /\blicen[cs]e\b/i
end
end
if license.nil?
:unlicensed
elsif classify_license(license)
:licensed
else
:unrecognized
end
end
unlicensed = submodule_licenses.select { |k,v| v.nil? }.reject { |k,v| PROJECT_WHITELIST.include?(k) }
message = "The following submodules don't have licenses:\n* #{unlicensed.keys.join("\n* ")}\n"
message << "Please ensure that the project has a LICENSE file, and that the LICENSE file contains the full text of the license."
assert_equal Hash.new, unlicensed, message
end
unlicensed = categories[:unlicensed] || []
unrecognized = categories[:unrecognized] || []
disallowed_unlicensed = unlicensed - LICENSE_WHITELIST
disallowed_unrecognized = unrecognized - LICENSE_WHITELIST
extra_whitelist_entries = LICENSE_WHITELIST - (unlicensed | unrecognized)
def test_submodules_have_approved_licenses
unapproved = submodule_licenses.reject { |k,v| LICENSE_WHITELIST.include?(v) || PROJECT_WHITELIST.include?(k) }.map { |k,v| "#{k}: #{v}"}
message = "The following submodules have unapproved licenses:\n* #{unapproved.join("\n* ")}\n"
message << "The license must be added to the LICENSE_WHITELIST in /test/test_grammars.rb once approved."
assert_equal [], unapproved, message
end
message = ""
if disallowed_unlicensed.any?
message << "The following grammar submodules don't seem to have a license. All grammars must have a license that permits redistribution.\n"
message << disallowed_unlicensed.sort.join("\n")
end
if disallowed_unrecognized.any?
message << "\n\n" unless message.empty?
message << "The following grammar submodules have an unrecognized license. Please update #{__FILE__} to recognize the license.\n"
message << disallowed_unrecognized.sort.join("\n")
end
if extra_whitelist_entries.any?
message << "\n\n" unless message.empty?
message << "The following grammar submodules are listed in LICENSE_WHITELIST but either have a license (yay!)\n"
message << "or have been removed from the repository. Please remove them from the whitelist.\n"
message << extra_whitelist_entries.sort.join("\n")
end
def test_submodules_whitelist_has_no_extra_entries
extra_whitelist_entries = PROJECT_WHITELIST - submodule_licenses.select { |k,v| v.nil? }.keys
not_present = extra_whitelist_entries.reject { |k,v| Dir.exists?(k) }
licensed = extra_whitelist_entries.select { |k,v| submodule_licenses[k] }
assert disallowed_unlicensed.empty? && disallowed_unrecognized.empty? && extra_whitelist_entries.empty?, message
msg = "The following whitelisted submodules don't appear to be part of the project:\n* #{not_present.join("\n* ")}"
assert_equal [], not_present, msg
msg = "The following whitelisted submodules actually have licenses and don't need to be whitelisted:\n* #{licensed.join("\n* ")}"
assert_equal [], licensed, msg
end
private
@@ -112,30 +119,57 @@ class TestGrammars < Minitest::Test
@submodule_paths ||= `git config --list --file "#{File.join(ROOT, ".gitmodules")}"`.lines.grep(/\.path=/).map { |line| line.chomp.split("=", 2).last }
end
# Returns a hash of submodules in the form of submodule_path => license
def submodule_licenses
@@submodule_licenses ||= begin
submodules = {}
submodule_paths.each { |submodule| submodules[submodule] = submodule_license(submodule) }
submodules
end
end
# Given the path to a submodule, return its SPDX-compliant license key
def submodule_license(submodule)
# Prefer Licensee to detect a submodule's license
project = Licensee::FSProject.new(submodule)
return project.license.key if project.license
# We know a license file exists, but Licensee wasn't able to detect the license,
# Let's try our own more permissive regex method
if project.license_file
path = File.expand_path project.license_file.path, submodule
license = classify_license(path)
return license if license
end
# Neither Licensee nor our own regex was able to detect the license, let's check the readme
files = Dir[File.join(ROOT, submodule, "*")]
if readme = files.find { |path| File.basename(path) =~ /\Areadme\b/i }
classify_license(readme)
end
end
def classify_license(path)
content = File.read(path)
return unless content =~ /\blicen[cs]e\b/i
if content.include?("Apache License") && content.include?("2.0")
"Apache 2.0"
"apache-2.0"
elsif content.include?("GNU") && content =~ /general/i && content =~ /public/i
if content =~ /version 2/i
"GPLv2"
"gpl-2.0"
elsif content =~ /version 3/i
"GPLv3"
"gpl-3.0"
end
elsif content.include?("GPL") && content.include?("http://www.gnu.org/licenses/gpl.html")
"GPLv3"
elsif content.include?("Creative Commons")
"CC"
"gpl-3.0"
elsif content.include?("Creative Commons Attribution-Share Alike 3.0")
"cc-by-sa-3.0"
elsif content.include?("tidy-license.txt") || content.include?("If not otherwise specified (see below)")
"textmate"
elsif content =~ /^\s*[*-]\s+Redistribution/ || content.include?("Redistributions of source code")
"BSD"
elsif content.include?("Permission is hereby granted") || content =~ /\bMIT\b/
"MIT"
elsif content.include?("unlicense.org")
"unlicense"
"mit"
elsif content.include?("http://www.wtfpl.net/txt/copying/")
"WTFPL"
"wtfpl"
elsif content.include?("zlib") && content.include?("license") && content.include?("2. Altered source versions must be plainly marked as such")
"zlib"
end

View File

@@ -33,6 +33,101 @@ class TestHeuristcs < Minitest::Test
end
end
def test_detect_still_works_if_nothing_matches
blob = Linguist::FileBlob.new(File.join(samples_path, "Objective-C/hello.m"))
match = Language.detect(blob)
assert_equal Language["Objective-C"], match
end
# Candidate languages = ["AGS Script", "AsciiDoc", "Public Key"]
def test_asc_by_heuristics
assert_heuristics({
"AsciiDoc" => all_fixtures("AsciiDoc", "*.asc"),
"AGS Script" => all_fixtures("AGS Script", "*.asc"),
"Public Key" => all_fixtures("Public Key", "*.asc")
})
end
def test_bb_by_heuristics
assert_heuristics({
"BitBake" => all_fixtures("BitBake", "*.bb"),
"BlitzBasic" => all_fixtures("BlitzBasic", "*.bb")
})
end
def test_ch_by_heuristics
assert_heuristics({
"xBase" => all_fixtures("xBase", ".ch")
})
end
def test_cl_by_heuristics
assert_heuristics({
"Common Lisp" => all_fixtures("Common Lisp", "*.cl"),
"OpenCL" => all_fixtures("OpenCL", "*.cl")
})
end
def test_cs_by_heuristics
assert_heuristics({
"C#" => all_fixtures("C#", "*.cs"),
"Smalltalk" => all_fixtures("Smalltalk", "*.cs")
})
end
# Candidate languages = ["ECL", "ECLiPSe"]
def test_ecl_by_heuristics
assert_heuristics({
"ECL" => all_fixtures("ECL", "*.ecl"),
"ECLiPSe" => all_fixtures("ECLiPSe", "*.ecl")
})
end
def test_f_by_heuristics
assert_heuristics({
"FORTRAN" => all_fixtures("FORTRAN", "*.f") + all_fixtures("FORTRAN", "*.for"),
"Forth" => all_fixtures("Forth", "*.f") + all_fixtures("Forth", "*.for")
})
end
def test_fr_by_heuristics
assert_heuristics({
"Frege" => all_fixtures("Frege", "*.fr"),
"Forth" => all_fixtures("Forth", "*.fr"),
"Text" => all_fixtures("Text", "*.fr")
})
end
def test_fs_by_heuristics
assert_heuristics({
"F#" => all_fixtures("F#", "*.fs"),
"Forth" => all_fixtures("Forth", "*.fs"),
"GLSL" => all_fixtures("GLSL", "*.fs")
})
end
# Candidate languages = ["Hack", "PHP"]
def test_hack_by_heuristics
assert_heuristics({
"Hack" => all_fixtures("Hack", "*.php"),
"PHP" => all_fixtures("PHP", "*.php")
})
end
def test_ls_by_heuristics
assert_heuristics({
"LiveScript" => all_fixtures("LiveScript", "*.ls"),
"LoomScript" => all_fixtures("LoomScript", "*.ls")
})
end
def test_lsp_by_heuristics
assert_heuristics({
"Common Lisp" => all_fixtures("Common Lisp", "*.lsp") + all_fixtures("Common Lisp", "*.lisp"),
"NewLisp" => all_fixtures("NewLisp", "*.lsp") + all_fixtures("NewLisp", "*.lisp")
})
end
# Candidate languages = ["C++", "Objective-C"]
def test_obj_c_by_heuristics
# Only calling out '.h' filenames as these are the ones causing issues
@@ -43,12 +138,6 @@ class TestHeuristcs < Minitest::Test
})
end
def test_detect_still_works_if_nothing_matches
blob = Linguist::FileBlob.new(File.join(samples_path, "Objective-C/hello.m"))
match = Language.detect(blob)
assert_equal Language["Objective-C"], match
end
# Candidate languages = ["Perl", "Perl6", "Prolog"]
def test_pl_prolog_perl_by_heuristics
assert_heuristics({
@@ -66,14 +155,6 @@ class TestHeuristcs < Minitest::Test
})
end
# Candidate languages = ["ECL", "Prolog"]
def test_ecl_prolog_by_heuristics
assert_heuristics({
"ECL" => all_fixtures("ECL", "*.ecl"),
"Prolog" => all_fixtures("Prolog", "*.ecl")
})
end
# Candidate languages = ["IDL", "Prolog", "QMake", "INI"]
def test_pro_by_heuristics
assert_heuristics({
@@ -84,34 +165,10 @@ class TestHeuristcs < Minitest::Test
})
end
# Candidate languages = ["AGS Script", "AsciiDoc", "Public Key"]
def test_asc_by_heuristics
def test_r_by_heuristics
assert_heuristics({
"AsciiDoc" => all_fixtures("AsciiDoc", "*.asc"),
"AGS Script" => all_fixtures("AGS Script", "*.asc"),
"Public Key" => all_fixtures("Public Key", "*.asc")
})
end
def test_cl_by_heuristics
assert_heuristics({
"Common Lisp" => all_fixtures("Common Lisp", "*.cl"),
"OpenCL" => all_fixtures("OpenCL", "*.cl")
})
end
def test_f_by_heuristics
assert_heuristics({
"FORTRAN" => all_fixtures("FORTRAN", "*.f") + all_fixtures("FORTRAN", "*.for"),
"Forth" => all_fixtures("Forth", "*.f") + all_fixtures("Forth", "*.for")
})
end
# Candidate languages = ["Hack", "PHP"]
def test_hack_by_heuristics
assert_heuristics({
"Hack" => all_fixtures("Hack", "*.php"),
"PHP" => all_fixtures("PHP", "*.php")
"R" => all_fixtures("R", "*.r") + all_fixtures("R", "*.R"),
"Rebol" => all_fixtures("Rebol", "*.r")
})
end
@@ -123,47 +180,13 @@ class TestHeuristcs < Minitest::Test
})
end
def test_fs_by_heuristics
# Candidate languages = ["Perl", "Perl6"]
def test_t_perl_by_heuristics
assert_heuristics({
"F#" => all_fixtures("F#", "*.fs"),
"Forth" => all_fixtures("Forth", "*.fs"),
"GLSL" => all_fixtures("GLSL", "*.fs")
})
end
def test_fr_by_heuristics
assert_heuristics({
"Frege" => all_fixtures("Frege", "*.fr"),
"Forth" => all_fixtures("Forth", "*.fr"),
"Text" => all_fixtures("Text", "*.fr")
})
end
def test_bb_by_heuristics
assert_heuristics({
"BitBake" => all_fixtures("BitBake", "*.bb"),
"BlitzBasic" => all_fixtures("BlitzBasic", "*.bb")
})
end
def test_lsp_by_heuristics
assert_heuristics({
"Common Lisp" => all_fixtures("Common Lisp", "*.lsp") + all_fixtures("Common Lisp", "*.lisp"),
"NewLisp" => all_fixtures("NewLisp", "*.lsp") + all_fixtures("NewLisp", "*.lisp")
})
end
def test_cs_by_heuristics
assert_heuristics({
"C#" => all_fixtures("C#", "*.cs"),
"Smalltalk" => all_fixtures("Smalltalk", "*.cs")
})
end
def test_ls_by_heuristics
assert_heuristics({
"LiveScript" => all_fixtures("LiveScript", "*.ls"),
"LoomScript" => all_fixtures("LoomScript", "*.ls")
"Perl" => all_fixtures("Perl", "*.t"),
"Perl6" => ["Perl6/01-dash-uppercase-i.t", "Perl6/01-parse.t", "Perl6/advent2009-day16.t",
"Perl6/basic-open.t", "Perl6/calendar.t", "Perl6/for.t", "Perl6/hash.t",
"Perl6/listquote-whitespace.t"]
})
end
@@ -173,17 +196,4 @@ class TestHeuristcs < Minitest::Test
"XML" => all_fixtures("XML", "*.ts")
})
end
def test_ch_by_heuristics
assert_heuristics({
"xBase" => all_fixtures("xBase", ".ch")
})
end
def test_r_by_heuristics
assert_heuristics({
"R" => all_fixtures("R", "*.r") + all_fixtures("R", "*.R"),
"Rebol" => all_fixtures("Rebol", "*.r")
})
end
end

View File

@@ -57,6 +57,7 @@ class TestLanguage < Minitest::Test
assert_equal Language['Shell'], Language.find_by_alias('sh')
assert_equal Language['Shell'], Language.find_by_alias('shell')
assert_equal Language['Shell'], Language.find_by_alias('zsh')
assert_equal Language['SuperCollider'], Language.find_by_alias('supercollider')
assert_equal Language['TeX'], Language.find_by_alias('tex')
assert_equal Language['TypeScript'], Language.find_by_alias('ts')
assert_equal Language['VimL'], Language.find_by_alias('vim')
@@ -119,6 +120,7 @@ class TestLanguage < Minitest::Test
assert_equal 'vim', Language['VimL'].search_term
assert_equal 'jsp', Language['Java Server Pages'].search_term
assert_equal 'rst', Language['reStructuredText'].search_term
assert_equal 'supercollider', Language['SuperCollider'].search_term
end
def test_popular
@@ -138,6 +140,7 @@ class TestLanguage < Minitest::Test
assert_equal :programming, Language['Ruby'].type
assert_equal :programming, Language['TypeScript'].type
assert_equal :programming, Language['Makefile'].type
assert_equal :programming, Language['SuperCollider'].type
end
def test_markup
@@ -227,7 +230,8 @@ class TestLanguage < Minitest::Test
"python" => "Python",
"python2" => "Python",
"python3" => "Python",
"sbcl" => "Common Lisp"
"sbcl" => "Common Lisp",
"sclang" => "SuperCollider"
}.each do |interpreter, language|
assert_equal [Language[language]], Language.find_by_interpreter(interpreter)
end
@@ -339,6 +343,7 @@ class TestLanguage < Minitest::Test
assert Language['Perl'].extensions.include?('.pl')
assert Language['Python'].extensions.include?('.py')
assert Language['Ruby'].extensions.include?('.rb')
assert Language['SuperCollider'].extensions.include?('.scd')
end
def test_primary_extension
@@ -349,6 +354,7 @@ class TestLanguage < Minitest::Test
assert_equal '.coffee', Language['CoffeeScript'].primary_extension
assert_equal '.t', Language['Turing'].primary_extension
assert_equal '.ts', Language['TypeScript'].primary_extension
assert_equal '.sc', Language['SuperCollider'].primary_extension
end
def test_eql

View File

@@ -9,7 +9,7 @@ class TestPedantic < Minitest::Test
assert_sorted LANGUAGES.keys
end
def test_extensions_are_sorted
def test_nonprimary_extensions_are_sorted
LANGUAGES.each do |name, language|
extensions = language['extensions']
assert_sorted extensions[1..-1].map(&:downcase) if extensions && extensions.size > 1
@@ -32,6 +32,18 @@ class TestPedantic < Minitest::Test
end
end
def test_heuristics_are_sorted
file = File.expand_path("../../lib/linguist/heuristics.rb", __FILE__)
heuristics = open(file).each.grep(/^ *disambiguate/)
assert_sorted heuristics
end
def test_heuristics_tests_are_sorted
file = File.expand_path("../test_heuristics.rb", __FILE__)
tests = open(file).each.grep(/^ *def test_[a-z_]+_by_heuristics/)
assert_sorted tests
end
def assert_sorted(list)
list.each_cons(2) do |previous, item|
flunk "#{previous} should come after #{item}" if previous > item

View File

@@ -111,4 +111,14 @@ class TestRepository < Minitest::Test
refute_predicate readme, :documentation?
assert_predicate arduino, :documentation?
end
def test_linguist_override_generated?
attr_commit = "351c1cc8fd57340839bdb400d7812332af80e9bd"
repo = linguist_repo(attr_commit).read_index
rakefile = Linguist::LazyBlob.new(rugged_repository, attr_commit, "Rakefile")
# overridden .gitattributes
assert rakefile.generated?
end
end

1
vendor/grammars/X10 vendored Submodule

Submodule vendor/grammars/X10 added at 2bae6e77fa

Some files were not shown because too many files have changed in this diff Show More