Merge branch 'master' into 1285-local

Conflicts:
	lib/linguist/language.rb
	lib/linguist/samples.json
This commit is contained in:
Arfon Smith
2014-07-09 12:46:18 -05:00
66 changed files with 74524 additions and 75133 deletions

View File

@@ -1,4 +1,6 @@
before_install:
- git fetch origin master:master
- git fetch origin v2.0.0:v2.0.0
- sudo apt-get install libicu-dev -y
- gem update --system 2.1.11
rvm:

View File

@@ -152,4 +152,4 @@ If you are the current maintainer of this gem:
0. Test behavior locally, branch deploy, whatever needs to happen
0. Merge github/linguist PR
0. Tag and push: `git tag vx.xx.xx; git push --tags`
0. Push to rubygems.org -- `gem push github-linguist-2.10.12.gem`
0. Push to rubygems.org -- `gem push github-linguist-3.0.0.gem`

View File

@@ -5,6 +5,7 @@
require 'linguist/file_blob'
require 'linguist/repository'
require 'rugged'
path = ARGV[0] || Dir.pwd
@@ -18,7 +19,8 @@ ARGV.shift
breakdown = true if ARGV[0] == "--breakdown"
if File.directory?(path)
repo = Linguist::Repository.from_directory(path)
rugged = Rugged::Repository.new(path)
repo = Linguist::Repository.new(rugged, rugged.head.target_id)
repo.languages.sort_by { |_, size| size }.reverse.each do |language, size|
percentage = ((size / repo.size.to_f) * 100)
percentage = sprintf '%.2f' % percentage

View File

@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
s.add_dependency 'escape_utils', '~> 1.0.1'
s.add_dependency 'mime-types', '~> 1.19'
s.add_dependency 'pygments.rb', '~> 0.6.0'
s.add_dependency 'rugged', '~> 0.21.0'
s.add_development_dependency 'json'
s.add_development_dependency 'mocha'

View File

@@ -313,15 +313,7 @@ module Linguist
#
# Returns a Language or nil if none is detected
def language
return @language if defined? @language
if defined?(@data) && @data.is_a?(String)
data = @data
else
data = lambda { (binary_mime_type? || binary?) ? "" : self.data }
end
@language = Language.detect(name.to_s, data, mode)
@language ||= Language.detect(self)
end
# Internal: Get the lexer of the blob.

View File

@@ -63,7 +63,8 @@ module Linguist
generated_jni_header? ||
composer_lock? ||
node_modules? ||
vcr_cassette?
vcr_cassette? ||
generated_by_zephir?
end
# Internal: Is the blob an XCode project file?
@@ -237,6 +238,13 @@ module Linguist
!!name.match(/composer.lock/)
end
# Internal: Is the blob a generated by Zephir
#
# Returns true or false.
def generated_by_zephir?
!!name.match(/.\.zep\.(?:c|h|php)$/)
end
# Is the blob a VCR Cassette file?
#
# Returns true or false

View File

@@ -92,14 +92,20 @@ module Linguist
# Public: Detects the Language of the blob.
#
# name - String filename
# data - String blob data. A block also maybe passed in for lazy
# loading. This behavior is deprecated and you should always
# pass in a String.
# mode - Optional String mode (defaults to nil)
# blob - an object that includes the Linguist `BlobHelper` interface;
# see Linguist::LazyBlob and Linguist::FileBlob for examples
#
# Returns Language or nil.
def self.detect(name, data, mode = nil)
def self.detect(blob)
name = blob.name.to_s
# Check if the blob is possibly binary and bail early; this is a cheap
# test that uses the extension name to guess a binary binary mime type.
#
# We'll perform a more comprehensive test later which actually involves
# looking for binary characters in the blob
return nil if blob.likely_binary? || blob.binary?
# A bit of an elegant hack. If the file is executable but extensionless,
# append a "magic" extension so it can be classified with other
# languages that have shebang scripts.
@@ -115,10 +121,10 @@ module Linguist
# extension at all, in the case of extensionless scripts), we need to continue
# our detection work
if possible_languages.length > 1
data = data.call() if data.respond_to?(:call)
data = blob.data
possible_language_names = possible_languages.map(&:name)
# Don't bother with emptiness
# Don't bother with binary contents or an empty file
if data.nil? || data == ""
nil
# Check if there's a shebang line and use that as authoritative

View File

@@ -89,7 +89,7 @@ Agda:
Alloy:
type: programming # 'modeling' would be more appropiate
lexer: Text only
lexer: Alloy
color: "#cc5c24"
extensions:
- .als
@@ -157,7 +157,6 @@ Assembly:
- nasm
extensions:
- .asm
- .inc
Augeas:
type: programming
@@ -222,6 +221,8 @@ BlitzBasic:
- .decls
BlitzMax:
type: programming
color: "#cd6400"
extensions:
- .bmx
@@ -529,15 +530,6 @@ Dart:
extensions:
- .dart
DCPU-16 ASM:
type: programming
lexer: dasm16
extensions:
- .dasm16
- .dasm
aliases:
- dasm16
Diff:
extensions:
- .diff
@@ -744,12 +736,14 @@ GLSL:
- .glsl
- .fp
- .frag
- .frg
- .fshader
- .geom
- .glslv
- .gshader
- .shader
- .vert
- .vrx
- .vshader
Genshi:
@@ -807,6 +801,12 @@ Gosu:
extensions:
- .gs
Grace:
type: programming
lexer: Text only
extensions:
- .grace
Grammatical Framework:
type: programming
lexer: Haskell
@@ -941,7 +941,7 @@ Hy:
IDL:
type: programming
lexer: Text only
lexer: IDL
color: "#e3592c"
extensions:
- .pro
@@ -960,7 +960,7 @@ Inno Setup:
Idris:
type: programming
lexer: Text only
lexer: Idris
extensions:
- .idr
- .lidr
@@ -1095,6 +1095,8 @@ JavaScript:
- .pac
- .sjs
- .ssjs
- .xsjs
- .xsjslib
filenames:
- Jakefile
interpreters:
@@ -1293,6 +1295,8 @@ Mathematica:
type: programming
extensions:
- .mathematica
- .m
- .nb
lexer: Text only
Matlab:
@@ -1400,6 +1404,19 @@ Nimrod:
- .nim
- .nimrod
Nit:
type: programming
lexer: Text only
color: "#0d8921"
extensions:
- .nit
Nix:
type: programming
lexer: Nix
extensions:
- .nix
Nu:
type: programming
lexer: Scheme
@@ -1535,6 +1552,8 @@ PHP:
- .phpt
filenames:
- Phakefile
interpreters:
- php
Pan:
type: programming
@@ -1609,7 +1628,7 @@ Perl6:
Pike:
type: programming
color: "#066ab2"
lexer: C
lexer: Pike
extensions:
- .pike
- .pmod
@@ -1706,6 +1725,7 @@ Python:
- .gyp
- .lmi
- .pyde
- .pyp
- .pyt
- .pyw
- .wsgi
@@ -1731,6 +1751,12 @@ QML:
extensions:
- .qml
QMake:
lexer: Text only
extensions:
- .pro
- .pri
R:
type: programming
color: "#198ce7"
@@ -1870,13 +1896,17 @@ Ruby:
interpreters:
- ruby
filenames:
- .pryrc
- Appraisals
- Berksfile
- Buildfile
- Gemfile
- Gemfile.lock
- Guardfile
- Jarfile
- Mavenfile
- Podfile
- Puppetfile
- Thorfile
- Vagrantfile
- buildfile

37
lib/linguist/lazy_blob.rb Normal file
View File

@@ -0,0 +1,37 @@
require 'linguist/blob_helper'
require 'rugged'
module Linguist
class LazyBlob
include BlobHelper
MAX_SIZE = 128 * 1024
attr_reader :repository
attr_reader :oid
attr_reader :name
attr_reader :mode
def initialize(repo, oid, name, mode = nil)
@repository = repo
@oid = oid
@name = name
@mode = mode
end
def data
load_blob!
@data
end
def size
load_blob!
@size
end
protected
def load_blob!
@data, @size = Rugged::Blob.to_buffer(repository, oid, MAX_SIZE) if @data.nil?
end
end
end

View File

@@ -1,4 +1,5 @@
require 'linguist/file_blob'
require 'linguist/lazy_blob'
require 'rugged'
module Linguist
# A Repository is an abstraction of a Grit::Repo or a basic file
@@ -7,100 +8,146 @@ module Linguist
# Its primary purpose is for gathering language statistics across
# the entire project.
class Repository
# Public: Initialize a new Repository from a File directory
#
# base_path - A path String
#
# Returns a Repository
def self.from_directory(base_path)
new Dir["#{base_path}/**/*"].
select { |f| File.file?(f) }.
map { |path| FileBlob.new(path, base_path) }
attr_reader :repository
# Public: Create a new Repository based on the stats of
# an existing one
def self.incremental(repo, commit_oid, old_commit_oid, old_stats)
repo = self.new(repo, commit_oid)
repo.load_existing_stats(old_commit_oid, old_stats)
repo
end
# Public: Initialize a new Repository
# Public: Initialize a new Repository to be analyzed for language
# data
#
# enum - Enumerator that responds to `each` and
# yields Blob objects
# repo - a Rugged::Repository object
# commit_oid - the sha1 of the commit that will be analyzed;
# this is usually the master branch
#
# Returns a Repository
def initialize(enum)
@enum = enum
@computed_stats = false
@language = @size = nil
@sizes = Hash.new { 0 }
@file_breakdown = Hash.new { |h,k| h[k] = Array.new }
def initialize(repo, commit_oid)
@repository = repo
@commit_oid = commit_oid
raise TypeError, 'commit_oid must be a commit SHA1' unless commit_oid.is_a?(String)
end
# Public: Load the results of a previous analysis on this repository
# to speed up the new scan.
#
# The new analysis will be performed incrementally as to only take
# into account the file changes since the last time the repository
# was scanned
#
# old_commit_oid - the sha1 of the commit that was previously analyzed
# old_stats - the result of the previous analysis, obtained by calling
# Repository#cache on the old repository
#
# Returns nothing
def load_existing_stats(old_commit_oid, old_stats)
@old_commit_oid = old_commit_oid
@old_stats = old_stats
nil
end
# Public: Returns a breakdown of language stats.
#
# Examples
#
# # => { Language['Ruby'] => 46319,
# Language['JavaScript'] => 258 }
# # => { 'Ruby' => 46319,
# 'JavaScript' => 258 }
#
# Returns a Hash of Language keys and Integer size values.
# Returns a Hash of language names and Integer size values.
def languages
compute_stats
@sizes
@sizes ||= begin
sizes = Hash.new { 0 }
cache.each do |_, (language, size)|
sizes[language] += size
end
sizes
end
end
# Public: Get primary Language of repository.
#
# Returns a Language
# Returns a language name
def language
compute_stats
@language
@language ||= begin
primary = languages.max_by { |(_, size)| size }
primary && primary[0]
end
end
# Public: Get the total size of the repository.
#
# Returns a byte size Integer
def size
compute_stats
@size
@size ||= languages.inject(0) { |s,(_,v)| s + v }
end
# Public: Return the language breakdown of this repository by file
#
# Returns a map of language names => [filenames...]
def breakdown_by_file
compute_stats
@file_breakdown
@file_breakdown ||= begin
breakdown = Hash.new { |h,k| h[k] = Array.new }
cache.each do |filename, (language, _)|
breakdown[language] << filename
end
breakdown
end
end
# Internal: Compute language breakdown for each blob in the Repository.
# Public: Return the cached results of the analysis
#
# Returns nothing
def compute_stats
return if @computed_stats
# This is a per-file breakdown that can be passed to other instances
# of Linguist::Repository to perform incremental scans
#
# Returns a map of filename => [language, size]
def cache
@cache ||= begin
if @old_commit_oid == @commit_oid
@old_stats
else
compute_stats(@old_commit_oid, @commit_oid, @old_stats)
end
end
end
@enum.each do |blob|
# Skip files that are likely binary
next if blob.likely_binary?
protected
def compute_stats(old_commit_oid, commit_oid, cache = nil)
file_map = cache ? cache.dup : {}
old_tree = old_commit_oid && Rugged::Commit.lookup(repository, old_commit_oid).tree
new_tree = Rugged::Commit.lookup(repository, commit_oid).tree
diff = Rugged::Tree.diff(repository, old_tree, new_tree)
diff.each_delta do |delta|
old = delta.old_file[:path]
new = delta.new_file[:path]
file_map.delete(old)
next if delta.binary
if [:added, :modified].include? delta.status
# Skip submodules
mode = delta.new_file[:mode]
next if (mode & 040000) != 0
blob = Linguist::LazyBlob.new(repository, delta.new_file[:oid], new, mode.to_s(8))
# Skip vendored or generated blobs
next if blob.vendored? || blob.generated? || blob.language.nil?
# Only include programming languages and acceptable markup languages
if blob.language.type == :programming || Language.detectable_markup.include?(blob.language.name)
# Build up the per-file breakdown stats
@file_breakdown[blob.language.group.name] << blob.name
@sizes[blob.language.group] += blob.size
file_map[new] = [blob.language.group.name, blob.size]
end
end
end
# Compute total size
@size = @sizes.inject(0) { |s,(_,v)| s + v }
# Get primary language
if primary = @sizes.max_by { |(_, size)| size }
@language = primary[0]
end
@computed_stats = true
nil
file_map
end
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,7 @@ module Linguist
#
# Returns nothing.
def self.each(&block)
Dir.entries(ROOT).each do |category|
Dir.entries(ROOT).sort!.each do |category|
next if category == '.' || category == '..'
# Skip text and binary for now

View File

@@ -40,9 +40,13 @@
- foundation.min.css
- foundation.css
# Normalize.css
- normalize.css
# Vendored dependencies
- thirdparty/
- vendors?/
- extern(al)?/
# Debian packaging
- ^debian/
@@ -124,6 +128,9 @@
## Obj-C ##
# Cocoapods
- ^Pods/
# Sparkle
- (^|/)Sparkle/

View File

@@ -1,3 +1,3 @@
module Linguist
VERSION = "2.12.0"
VERSION = "3.0.3"
end

File diff suppressed because it is too large Load Diff

View File

@@ -1,503 +0,0 @@
; flat assembler interface for Win32
; Copyright (c) 1999-2014, Tomasz Grysztar.
; All rights reserved.
CREATE_NEW = 1
CREATE_ALWAYS = 2
OPEN_EXISTING = 3
OPEN_ALWAYS = 4
TRUNCATE_EXISTING = 5
FILE_SHARE_READ = 1
FILE_SHARE_WRITE = 2
FILE_SHARE_DELETE = 4
GENERIC_READ = 80000000h
GENERIC_WRITE = 40000000h
STD_INPUT_HANDLE = 0FFFFFFF6h
STD_OUTPUT_HANDLE = 0FFFFFFF5h
STD_ERROR_HANDLE = 0FFFFFFF4h
MEM_COMMIT = 1000h
MEM_RESERVE = 2000h
MEM_DECOMMIT = 4000h
MEM_RELEASE = 8000h
MEM_FREE = 10000h
MEM_PRIVATE = 20000h
MEM_MAPPED = 40000h
MEM_RESET = 80000h
MEM_TOP_DOWN = 100000h
PAGE_NOACCESS = 1
PAGE_READONLY = 2
PAGE_READWRITE = 4
PAGE_WRITECOPY = 8
PAGE_EXECUTE = 10h
PAGE_EXECUTE_READ = 20h
PAGE_EXECUTE_READWRITE = 40h
PAGE_EXECUTE_WRITECOPY = 80h
PAGE_GUARD = 100h
PAGE_NOCACHE = 200h
init_memory:
xor eax,eax
mov [memory_start],eax
mov eax,esp
and eax,not 0FFFh
add eax,1000h-10000h
mov [stack_limit],eax
mov eax,[memory_setting]
shl eax,10
jnz allocate_memory
push buffer
call [GlobalMemoryStatus]
mov eax,dword [buffer+20]
mov edx,dword [buffer+12]
cmp eax,0
jl large_memory
cmp edx,0
jl large_memory
shr eax,2
add eax,edx
jmp allocate_memory
large_memory:
mov eax,80000000h
allocate_memory:
mov edx,eax
shr edx,2
mov ecx,eax
sub ecx,edx
mov [memory_end],ecx
mov [additional_memory_end],edx
push PAGE_READWRITE
push MEM_COMMIT
push eax
push 0
call [VirtualAlloc]
or eax,eax
jz not_enough_memory
mov [memory_start],eax
add eax,[memory_end]
mov [memory_end],eax
mov [additional_memory],eax
add [additional_memory_end],eax
ret
not_enough_memory:
mov eax,[additional_memory_end]
shl eax,1
cmp eax,4000h
jb out_of_memory
jmp allocate_memory
exit_program:
movzx eax,al
push eax
mov eax,[memory_start]
test eax,eax
jz do_exit
push MEM_RELEASE
push 0
push eax
call [VirtualFree]
do_exit:
call [ExitProcess]
get_environment_variable:
mov ecx,[memory_end]
sub ecx,edi
cmp ecx,4000h
jbe buffer_for_variable_ok
mov ecx,4000h
buffer_for_variable_ok:
push ecx
push edi
push esi
call [GetEnvironmentVariable]
add edi,eax
cmp edi,[memory_end]
jae out_of_memory
ret
open:
push 0
push 0
push OPEN_EXISTING
push 0
push FILE_SHARE_READ
push GENERIC_READ
push edx
call [CreateFile]
cmp eax,-1
je file_error
mov ebx,eax
clc
ret
file_error:
stc
ret
create:
push 0
push 0
push CREATE_ALWAYS
push 0
push FILE_SHARE_READ
push GENERIC_WRITE
push edx
call [CreateFile]
cmp eax,-1
je file_error
mov ebx,eax
clc
ret
write:
push 0
push bytes_count
push ecx
push edx
push ebx
call [WriteFile]
or eax,eax
jz file_error
clc
ret
read:
mov ebp,ecx
push 0
push bytes_count
push ecx
push edx
push ebx
call [ReadFile]
or eax,eax
jz file_error
cmp ebp,[bytes_count]
jne file_error
clc
ret
close:
push ebx
call [CloseHandle]
ret
lseek:
movzx eax,al
push eax
push 0
push edx
push ebx
call [SetFilePointer]
ret
display_string:
push [con_handle]
call [GetStdHandle]
mov ebp,eax
mov edi,esi
or ecx,-1
xor al,al
repne scasb
neg ecx
sub ecx,2
push 0
push bytes_count
push ecx
push esi
push ebp
call [WriteFile]
ret
display_character:
push ebx
mov [character],dl
push [con_handle]
call [GetStdHandle]
mov ebx,eax
push 0
push bytes_count
push 1
push character
push ebx
call [WriteFile]
pop ebx
ret
display_number:
push ebx
mov ecx,1000000000
xor edx,edx
xor bl,bl
display_loop:
div ecx
push edx
cmp ecx,1
je display_digit
or bl,bl
jnz display_digit
or al,al
jz digit_ok
not bl
display_digit:
mov dl,al
add dl,30h
push ecx
call display_character
pop ecx
digit_ok:
mov eax,ecx
xor edx,edx
mov ecx,10
div ecx
mov ecx,eax
pop eax
or ecx,ecx
jnz display_loop
pop ebx
ret
display_user_messages:
mov [displayed_count],0
call show_display_buffer
cmp [displayed_count],1
jb line_break_ok
je make_line_break
mov ax,word [last_displayed]
cmp ax,0A0Dh
je line_break_ok
cmp ax,0D0Ah
je line_break_ok
make_line_break:
mov word [buffer],0A0Dh
push [con_handle]
call [GetStdHandle]
push 0
push bytes_count
push 2
push buffer
push eax
call [WriteFile]
line_break_ok:
ret
display_block:
add [displayed_count],ecx
cmp ecx,1
ja take_last_two_characters
jb block_displayed
mov al,[last_displayed+1]
mov ah,[esi]
mov word [last_displayed],ax
jmp block_ok
take_last_two_characters:
mov ax,[esi+ecx-2]
mov word [last_displayed],ax
block_ok:
push ecx
push [con_handle]
call [GetStdHandle]
pop ecx
push 0
push bytes_count
push ecx
push esi
push eax
call [WriteFile]
block_displayed:
ret
fatal_error:
mov [con_handle],STD_ERROR_HANDLE
mov esi,error_prefix
call display_string
pop esi
call display_string
mov esi,error_suffix
call display_string
mov al,0FFh
jmp exit_program
assembler_error:
mov [con_handle],STD_ERROR_HANDLE
call display_user_messages
push dword 0
mov ebx,[current_line]
get_error_lines:
mov eax,[ebx]
cmp byte [eax],0
je get_next_error_line
push ebx
test byte [ebx+7],80h
jz display_error_line
mov edx,ebx
find_definition_origin:
mov edx,[edx+12]
test byte [edx+7],80h
jnz find_definition_origin
push edx
get_next_error_line:
mov ebx,[ebx+8]
jmp get_error_lines
display_error_line:
mov esi,[ebx]
call display_string
mov esi,line_number_start
call display_string
mov eax,[ebx+4]
and eax,7FFFFFFFh
call display_number
mov dl,']'
call display_character
pop esi
cmp ebx,esi
je line_number_ok
mov dl,20h
call display_character
push esi
mov esi,[esi]
movzx ecx,byte [esi]
inc esi
call display_block
mov esi,line_number_start
call display_string
pop esi
mov eax,[esi+4]
and eax,7FFFFFFFh
call display_number
mov dl,']'
call display_character
line_number_ok:
mov esi,line_data_start
call display_string
mov esi,ebx
mov edx,[esi]
call open
mov al,2
xor edx,edx
call lseek
mov edx,[esi+8]
sub eax,edx
jz line_data_displayed
push eax
xor al,al
call lseek
mov ecx,[esp]
mov edx,[additional_memory]
lea eax,[edx+ecx]
cmp eax,[additional_memory_end]
ja out_of_memory
call read
call close
pop ecx
mov esi,[additional_memory]
get_line_data:
mov al,[esi]
cmp al,0Ah
je display_line_data
cmp al,0Dh
je display_line_data
cmp al,1Ah
je display_line_data
or al,al
jz display_line_data
inc esi
loop get_line_data
display_line_data:
mov ecx,esi
mov esi,[additional_memory]
sub ecx,esi
call display_block
line_data_displayed:
mov esi,cr_lf
call display_string
pop ebx
or ebx,ebx
jnz display_error_line
mov esi,error_prefix
call display_string
pop esi
call display_string
mov esi,error_suffix
call display_string
mov al,2
jmp exit_program
make_timestamp:
push buffer
call [GetSystemTime]
movzx ecx,word [buffer]
mov eax,ecx
sub eax,1970
mov ebx,365
mul ebx
mov ebp,eax
mov eax,ecx
sub eax,1969
shr eax,2
add ebp,eax
mov eax,ecx
sub eax,1901
mov ebx,100
div ebx
sub ebp,eax
mov eax,ecx
xor edx,edx
sub eax,1601
mov ebx,400
div ebx
add ebp,eax
movzx ecx,word [buffer+2]
mov eax,ecx
dec eax
mov ebx,30
mul ebx
add ebp,eax
cmp ecx,8
jbe months_correction
mov eax,ecx
sub eax,7
shr eax,1
add ebp,eax
mov ecx,8
months_correction:
mov eax,ecx
shr eax,1
add ebp,eax
cmp ecx,2
jbe day_correction_ok
sub ebp,2
movzx ecx,word [buffer]
test ecx,11b
jnz day_correction_ok
xor edx,edx
mov eax,ecx
mov ebx,100
div ebx
or edx,edx
jnz day_correction
mov eax,ecx
mov ebx,400
div ebx
or edx,edx
jnz day_correction_ok
day_correction:
inc ebp
day_correction_ok:
movzx eax,word [buffer+6]
dec eax
add eax,ebp
mov ebx,24
mul ebx
movzx ecx,word [buffer+8]
add eax,ecx
mov ebx,60
mul ebx
movzx ecx,word [buffer+10]
add eax,ecx
mov ebx,60
mul ebx
movzx ecx,word [buffer+12]
add eax,ecx
adc edx,0
ret
error_prefix db 'error: ',0
error_suffix db '.'
cr_lf db 0Dh,0Ah,0
line_number_start db ' [',0
line_data_start db ':',0Dh,0Ah,0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
SuperStrict
Framework Brl.StandardIO
Type TMyType
Field property:int
Function A:int(param:int)
'do nothing
End Function
Method B:int(param:int)
'do nothing
End Method
End Type
Global my:TMyType = new TMyType
?Win32
my.A()
my.B()
?Linux
my.B()
my.A()
?

View File

@@ -0,0 +1,6 @@
varying vec4 v_color;
void main()
{
gl_FragColor = v_color;
}

12
samples/GLSL/myvertex.vrx Normal file
View File

@@ -0,0 +1,12 @@
uniform mat4 u_MVPMatrix;
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 v_color;
void main()
{
v_color = a_color;
gl_Position = u_MVPMatrix * pos;
}

View File

@@ -0,0 +1,6 @@
method ack (m : Number, n : Number) -> Number {
print "ack {m} {n}"
if (m < = 0) then {n + 1}
elseif {n <= 0} then {ack((m -1), 1)}
else {ack(m -1, ack(m, n-1))}
}

View File

@@ -0,0 +1,554 @@
import "gtk" as gtk
import "io" as io
import "mgcollections" as collections
import "button_factory" as button_factory
import "dialog_factory" as dialog_factory
import "syntax_highlighter" as highlighter
import "auto_completer" as aComp
//TODO
// Autocomplete typing
// FileChooser
// Themes
// Details for the Top Level Window
def window = gtk.window(gtk.GTK_WINDOW_TOPLEVEL)
window.title := "Grace"
window.set_default_size(700, 700)
// -------------
// Placeholder for the console window that can be popped out
// of the main window
var popped := gtk.window(gtk.GTK_WINDOW_TOPLEVEL)
// Initialise the Boxes
def mBox = gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2)
def buttonBox = gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 2)
var consoleButtons := gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 3)
var consoleBox := gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2)
var editorBox := gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2)
var splitPane := gtk.paned(gtk.GTK_ORIENTATION_VERTICAL, 2)
def menuBox = gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 4)
// -------------
// Initialise the buttons
def runButton = button_factory.make("run")
var clearButton := button_factory.make("clear")
var outButton := button_factory.make("out")
var errorButton := button_factory.make("error")
var popButton := button_factory.make("pop")
def newButton = button_factory.make("new")
def openButton = button_factory.make("open")
def saveButton = button_factory.make("save")
def saveAsButton = button_factory.make("saveAs")
def closeButton = button_factory.make("close")
// -------------
// Details for the default text editor and scrolled window
var tEdit := gtk.text_view
tEdit.set_size_request(700, 400)
var scrolled_main := gtk.scrolled_window
scrolled_main.set_size_request(700, 400)
scrolled_main.add(tEdit)
// -------------
// Widget that allows multiple files to be edited (tabs)
var notebook := gtk.notebook
notebook.scrollable := true
// -------------
// Maps for holding the text_views and scrolled_windows
var editor_map := collections.map.new
editor_map.put(0, tEdit)
var scrolled_map := collections.map.new
scrolled_map.put(0, scrolled_main)
// -------------
// Class that manages the syntax highlighting (This needs to be passed around otherwise
// the text_tag table gets confused, ie there can only be one)
def lighter = highlighter.Syntax_Highlighter.new(notebook, editor_map)
tEdit.buffer.on "changed" do {
lighter.highlightLine
}
// Class that manages any auto completion that is required
def completer = aComp.Auto_Completer.new(window, notebook, editor_map)
// Utility methods
// -------------
method deleteCompileFiles(page_num : Number) {
def cur_scrolled = scrolled_map.get(page_num)
var filename := notebook.get_tab_label_text(cur_scrolled)
filename := filename.substringFrom(0)to(filename.size - 7) //Removes .grace extension
io.system("rm -f files/" ++ filename)
io.system("rm -f files/" ++ filename ++ ".c")
io.system("rm -f files/" ++ filename ++ ".gcn")
io.system("rm -f files/" ++ filename ++ ".gct")
}
// -------------
var currentConsole := "output" // Which console is being shown
var out := false
var outText := ""
var errorText := ""
// Give actions to the buttons
// -------------
runButton.on "clicked" do {
clearConsoles()
// Get the details for the current page selected
def cur_page_num = notebook.current_page
def cur_page = editor_map.get(cur_page_num)
def cur_scrolled = scrolled_map.get(cur_page_num)
def cur_page_label = notebook.get_tab_label_text(cur_scrolled)
// Initialise text iterators
def sIter = gtk.text_iter
def eIter = gtk.text_iter
// Set one at the beggining and one at the end of the text
cur_page.buffer.get_iter_at_offset(sIter, 0)
cur_page.buffer.get_iter_at_offset(eIter, -1)
// Get the text between the text iterators
def text = cur_page.buffer.get_text(sIter, eIter, true)
// Save the text to the file (in case the user hasn't already saved it)
def file = io.open("files/" ++ cur_page_label, "w")
file.write(text)
file.close
// Run the program and pipe the output and errors into files to be read
io.system("../minigrace/minigrace " ++ "files/" ++ cur_page_label ++ " > output.txt 2> error.txt")
def outputFile = io.open("output.txt", "r")
def errorFile = io.open("error.txt", "r")
outText := outputFile.read
errorText := errorFile.read
io.system("rm -f output.txt error.txt")
var switched := false
// Change the console to output if there is output text
if((outText.size > 0) && (currentConsole != "output")) then {
switch_to_output()
switched := true
}
// Change the console to errors if there were errors
if((errorText.size > 0) && (currentConsole != "errors")) then {
switch_to_errors()
switched := true
}
// Remember to populate the console if it wasn't switched
if(!switched) then {
populateConsoles
}
}
clearButton.on "clicked" do {
clearConsoles()
}
outButton.on "clicked" do {
switch_to_output()
}
errorButton.on "clicked" do {
switch_to_errors()
}
popButton.on "clicked" do {
if(out) then {
popIn()
} else {
popOut()
}
}
// Gives a dialog to let the user create a new file to edit
newButton.on "clicked" do {
def new_window_class = dialog_factory.new.new(notebook, editor_map, scrolled_map, lighter)
def new_window = new_window_class.window()
new_window.show_all
}
// Gives a dialog that lets the user open a file to edit
openButton.on "clicked" do {
def open_window_class = dialog_factory.open.new(notebook, editor_map, scrolled_map, lighter)
def open_window = open_window_class.window()
open_window.show_all
}
// Saves the current file (if the name is Untitled.grace it will ask for a new name)
saveButton.on "clicked" do {
def cur_page_num = notebook.current_page
def cur_page = editor_map.get(cur_page_num)
def cur_scrolled = scrolled_map.get(cur_page_num)
def cur_page_label = notebook.get_tab_label_text(cur_scrolled)
if(cur_page_label == "Untitled.grace") then {
def saveAs_window_class = dialog_factory.save.new(notebook, editor_map, scrolled_map, true)
def saveAs_window = saveAs_window_class.window()
saveAs_window.show_all
} else {
// Initialise text iterators
def sIter = gtk.text_iter
def eIter = gtk.text_iter
// Set one at the beggining and one at the end of the text
cur_page.buffer.get_iter_at_offset(sIter, 0)
cur_page.buffer.get_iter_at_offset(eIter, -1)
// Get the text between the text iterators
def text = cur_page.buffer.get_text(sIter, eIter, true)
// Save the file
def file = io.open("files/" ++ cur_page_label, "w")
file.write(text)
file.close
}
}
// Gives a dialog that lets the user save the file with a new name
saveAsButton.on "clicked" do {
def saveAs_window_class = dialog_factory.save.new(notebook, editor_map, scrolled_map, false)
def saveAs_window = saveAs_window_class.window()
saveAs_window.show_all
}
// This will close a tab on the notebook
// It also "removes" the page from the map,
// by creating a new temporary map and putting all but
// the removed page in.
closeButton.on "clicked" do {
def page_num = notebook.current_page
def num_pages = notebook.n_pages
if(num_pages > 1) then {
deleteCompileFiles(page_num)
def e_map = collections.map.new
def s_map = collections.map.new
// Copy every page up to the current page into the new maps
var x := 0
while {x < page_num} do {
var eValue := editor_map.get(x)
var sValue := scrolled_map.get(x)
e_map.put(x, eValue)
s_map.put(x, sValue)
x := x + 1
}
// Copy every page after the current page into the new map (shifted one down)
x := page_num + 1
while {x < num_pages} do {
var eValue := editor_map.get(x)
var sValue := scrolled_map.get(x)
e_map.put((x - 1), eValue)
s_map.put((x - 1), sValue)
x := x + 1
}
editor_map := e_map
scrolled_map := s_map
notebook.remove_page(page_num)
notebook.show_all
}
}
// -------------
// Consoles:
// -------------
var outConsole := gtk.text_view
var outScroll := gtk.scrolled_window
var errorConsole := gtk.text_view
var errorScroll := gtk.scrolled_window
var errorTag := errorConsole.buffer.create_tag("fixed", "foreground", "red")
// Creates a new output console
method createOut {
outConsole := gtk.text_view
outScroll := gtk.scrolled_window
outScroll.add(outConsole)
if(out) then {
outConsole.set_size_request(400, 400)
outScroll.set_size_request(400, 400)
} else {
outConsole.set_size_request(700, 200)
outScroll.set_size_request(700, 200)
}
outConsole.editable := false
outConsole.buffer.set_text("[Output]:", -1)
}
createOut()
// Creates a new error console
method createError {
errorConsole := gtk.text_view
errorScroll := gtk.scrolled_window
errorScroll.add(errorConsole)
if(out) then {
errorConsole.set_size_request(400, 400)
errorScroll.set_size_request(400, 400)
} else {
errorConsole.set_size_request(700, 200)
errorScroll.set_size_request(700, 200)
}
errorConsole.editable := false
errorConsole.buffer.set_text("[Errors]:", -1)
errorTag := errorConsole.buffer.create_tag("fixed", "foreground", "red")
}
createError()
// Switches the console being shown to be output. This requires
// the output console to be remade as it would have been destroyed when
// it was switched previously
method switch_to_output {
if(currentConsole != "output") then {
currentConsole := "output"
consoleBox.remove(errorScroll) // This destroys the errorConsole
createOut()
consoleBox.add(outScroll)
populateConsoles()
if(out) then {
popped.show_all
} else {
window.show_all
}
}
}
// Switches the console being shown to be errors. This requires
// the error console to be remade as it would have been destroyed when
// it was switched previously
method switch_to_errors {
if(currentConsole != "errors") then {
currentConsole := "errors"
consoleBox.remove(outScroll) // This destroys the outConsole
createError()
consoleBox.add(errorScroll)
populateConsoles()
if(out) then {
popped.show_all
} else {
window.show_all
}
}
}
// If there is text to be put into the consoles this will add it
method populateConsoles {
if((outText.size > 0) && (currentConsole == "output")) then {
outConsole.buffer.set_text(outText, -1)
}
if((errorText.size > 0) && (currentConsole == "errors")) then {
def sIter = gtk.text_iter
def eIter = gtk.text_iter
errorConsole.buffer.set_text(errorText, -1)
errorConsole.buffer.get_iter_at_offset(sIter, 0)
errorConsole.buffer.get_iter_at_offset(eIter, -1)
errorConsole.buffer.apply_tag(errorTag, sIter, eIter)
}
}
method clearConsoles {
if(currentConsole == "output") then {
outConsole.buffer.set_text("[Output]:", -1)
outText := ""
}
if(currentConsole == "errors") then {
errorConsole.buffer.set_text("[Errors]:", -1)
errorText := ""
}
}
// Identical as the popIn method, but can be connected to the window's destroy button
def popInBlock = {
consoleBox.reparent(splitPane)
popButton.label := "Pop Out"
if(currentConsole == "output") then {
outConsole.set_size_request(700, 200)
outScroll.set_size_request(700, 200)
}
if(currentConsole == "errors") then {
errorConsole.set_size_request(700, 200)
errorScroll.set_size_request(700, 200)
}
def cur_page_num = notebook.current_page
def cur_scrolled = scrolled_map.get(cur_page_num)
def cur_page = editor_map.get(cur_page_num)
cur_page.set_size_request(700, 400)
cur_scrolled.set_size_request(700, 400)
out := false
popped.visible := false
}
// This pops the console out into a separate window
method popOut {
popped := gtk.window(gtk.GTK_WINDOW_TOPLEVEL)
consoleBox.reparent(popped)
popButton.label := "Pop In"
if(currentConsole == "output") then {
outConsole.set_size_request(400, 400)
outScroll.set_size_request(400, 400)
}
if(currentConsole == "errors") then {
errorConsole.set_size_request(400, 400)
errorScroll.set_size_request(400, 400)
}
def cur_page_num = notebook.current_page
def cur_scrolled = scrolled_map.get(cur_page_num)
def cur_page = editor_map.get(cur_page_num)
cur_page.set_size_request(700, 580)
cur_scrolled.set_size_request(700, 580)
out := true
popped.visible := true
popped.connect("destroy", popInBlock)
popped.show_all
}
// Puts the console back into the main window
method popIn {
consoleBox.reparent(splitPane)
popButton.label := "Pop Out"
if(currentConsole == "output") then {
outConsole.set_size_request(700, 200)
outScroll.set_size_request(700, 200)
}
if(currentConsole == "errors") then {
errorConsole.set_size_request(700, 200)
errorScroll.set_size_request(700, 200)
}
def cur_page_num = notebook.current_page
def cur_scrolled = scrolled_map.get(cur_page_num)
def cur_page = editor_map.get(cur_page_num)
cur_page.set_size_request(700, 400)
cur_scrolled.set_size_request(700, 400)
out := false
popped.visible := false
}
clearConsoles()
// -------------
// Patch everything together
var hSeparator1 := gtk.separator(gtk.GTK_ORIENTATION_HORIZONTAL)
var hSeparator2 := gtk.separator(gtk.GTK_ORIENTATION_HORIZONTAL)
menuBox.add(newButton)
menuBox.add(openButton)
menuBox.add(saveButton)
menuBox.add(saveAsButton)
buttonBox.add(runButton)
buttonBox.add(closeButton)
consoleButtons.add(outButton)
consoleButtons.add(errorButton)
consoleButtons.add(clearButton)
consoleButtons.add(popButton)
consoleBox.add(hSeparator1)
consoleBox.add(consoleButtons)
consoleBox.add(outScroll)
editorBox.add(hSeparator2)
notebook.add(scrolled_main)
notebook.set_tab_label_text(scrolled_main, "Untitled.grace")
editorBox.add(notebook)
splitPane.add1(editorBox)
splitPane.add2(consoleBox)
mBox.add(menuBox)
mBox.add(buttonBox)
mBox.add(splitPane)
window.add(mBox)
def exit = {
var x := 0
while {x < notebook.n_pages} do {
deleteCompileFiles(x)
x := x + 1
}
// Delete the compile files of the IDE
io.system("rm -f Grace_IDE.gct Grace_IDE.c Grace_IDE.gcn")
io.system("rm -f scanner.gct scanner.c scanner.gcn")
io.system("rm -f syntax_highlighter.gct syntax_highlighter.c syntax_highlighter.gcn")
io.system("rm -f syntax_colors.gct syntax_colors.c syntax_colors.gcn")
io.system("rm -f button_factory.gct button_factory.c button_factory.gcn")
io.system("rm -f dialog_factory.gct dialog_factory.c dialog_factory.gcn")
io.system("rm -f auto_completer.gct auto_completer.c auto_completer.gcn")
print "Grace IDE Closed Successfully"
gtk.main_quit
}
window.connect("destroy", exit)
window.show_all
gtk.main

View File

@@ -0,0 +1,24 @@
/*
invoke endpoint by calling in a browser:
http://<hanaserveradress>:<xsengineport(usually 8000)>/<path>/<to>/<endpoint>/helloHanaMath.xsjslib?x=4&y=2
e.g.:
http://192.168.178.20:8000/geekflyer/linguist/helloHanaEndpoint.xsjs?x=4&y=2
*/
var hanaMath = $.import("./helloHanaMath.xsjslib");
var x = parseFloat($.request.parameters.get("x"));
var y = parseFloat($.request.parameters.get("y"));
var result = hanaMath.multiply(x, y);
var output = {
title: "Hello HANA XS - do some simple math",
input: {x: x, y: y},
result: result
};
$.response.contentType = "application/json";
$.response.statusCode = $.net.http.OK;
$.response.setBody(JSON.stringify(output));

View File

@@ -0,0 +1,9 @@
/* simple hana xs demo library, which can be used by multiple endpoints */
function multiply(x, y) {
return x * y;
}
function add(x, y) {
return x + y;
}

View File

@@ -0,0 +1,232 @@
(* Content-type: application/vnd.wolfram.mathematica *)
(*** Wolfram Notebook File ***)
(* http://www.wolfram.com/nb *)
(* CreatedBy='Mathematica 9.0' *)
(*CacheID: 234*)
(* Internal cache information:
NotebookFileLineBreakTest
NotebookFileLineBreakTest
NotebookDataPosition[ 157, 7]
NotebookDataLength[ 7164, 223]
NotebookOptionsPosition[ 6163, 182]
NotebookOutlinePosition[ 6508, 197]
CellTagsIndexPosition[ 6465, 194]
WindowFrame->Normal*)
(* Beginning of Notebook Content *)
Notebook[{
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{
RowBox[{"Solve", "[",
RowBox[{
RowBox[{"y", "'"}], "\[Equal]", " ", "xy"}], "]"}],
"\[IndentingNewLine]"}]], "Input",
CellChangeTimes->{{3.6112716342092056`*^9, 3.6112716549793935`*^9}}],
Cell[BoxData[
RowBox[{"{",
RowBox[{"{",
RowBox[{"xy", "\[Rule]",
SuperscriptBox["y", "\[Prime]",
MultilineFunction->None]}], "}"}], "}"}]], "Output",
CellChangeTimes->{3.6112716579295626`*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"Log", "[",
RowBox[{"Sin", "[", "38", "]"}], "]"}]], "Input",
CellChangeTimes->{{3.611271663920905*^9, 3.6112716759275913`*^9}}],
Cell[BoxData[
RowBox[{"Log", "[",
RowBox[{"Sin", "[", "38", "]"}], "]"}]], "Output",
CellChangeTimes->{3.611271678256725*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"N", "[",
RowBox[{"Log", "[",
RowBox[{"Sin", "[", "38", "]"}], "]"}], "]"}]], "Input",
NumberMarks->False],
Cell[BoxData[
RowBox[{"-", "1.2161514009320473`"}]], "Output",
CellChangeTimes->{3.611271682061942*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"Abs", "[",
RowBox[{"-", "1.2161514009320473`"}], "]"}]], "Input",
NumberMarks->False],
Cell[BoxData["1.2161514009320473`"], "Output",
CellChangeTimes->{3.6112716842780695`*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"RealDigits", "[", "1.2161514009320473`", "]"}]], "Input",
NumberMarks->False],
Cell[BoxData[
RowBox[{"{",
RowBox[{
RowBox[{"{",
RowBox[{
"1", ",", "2", ",", "1", ",", "6", ",", "1", ",", "5", ",", "1", ",", "4",
",", "0", ",", "0", ",", "9", ",", "3", ",", "2", ",", "0", ",", "4",
",", "7"}], "}"}], ",", "1"}], "}"}]], "Output",
CellChangeTimes->{3.611271685319129*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{
RowBox[{"Graph", "[",
RowBox[{"Log", "[", "x", "]"}], "]"}], "\[IndentingNewLine]"}]], "Input",
CellChangeTimes->{{3.611271689258354*^9, 3.611271702038085*^9}}],
Cell[BoxData[
RowBox[{"Graph", "[",
RowBox[{"Log", "[", "x", "]"}], "]"}]], "Output",
CellChangeTimes->{3.611271704295214*^9}]
}, Open ]],
Cell[BoxData[""], "Input",
CellChangeTimes->{{3.611271712769699*^9, 3.6112717423153887`*^9}}],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{
RowBox[{"Plot", "[",
RowBox[{
RowBox[{"Log", "[", "x", "]"}], ",", " ",
RowBox[{"{",
RowBox[{"x", ",", " ", "0", ",", " ", "10"}], "}"}]}], "]"}],
"\[IndentingNewLine]"}]], "Input",
CellChangeTimes->{{3.6112717573482485`*^9, 3.6112717747822456`*^9}}],
Cell[BoxData[
GraphicsBox[{{}, {},
{Hue[0.67, 0.6, 0.6], LineBox[CompressedData["
1:eJwVzXs81Pkex/GZH7XlsutSQprwqxTSZVfJGp9P6UYqlyxHUhTaLrq4JpVK
0SHRisGWjYiEbHSvb+Q27rllmYwaY6JpwxgZTI7zx/vxejz/eht4H3PyoRgM
Rsj0/t+1MEPjP1Zc8O6L0tCYkJERTokxP5YLLR+MQy2qZWSzX62gWcaFn9s7
5sVFyohY4ZvLs5Ya6AheLQxnyIgFe4fllag6yH4zayhMcYw0FU5SRl8bweS/
wyVFa0aJBsz2VDVrAl8V299DGKPk1yWJllEHmqD42vuI4RopiRvJlYS9bYLZ
a2c4j3pJyS8JbT7eeW/By6ht44vkEXKuxtRu1d4WOB5QmStjSUhO0eMleTda
4EZtHmU5PEyaORsUFte1QFHRg6WjFcNkkZ/bC+11rVC0s8n9nf8wqVGINGNo
tkFRzD3HsYohosXu0misbAdxXml1VdQgKSi80nXErBNo/oP47aliMqAxEGvn
1QlVgoRvezzExCjYznppYifkn+K6CVli8peV8m2BrBNM20LljlmfyXVurK97
RRfcVCpPCXg8QIIF14a2eLyHn6Y4909//UTSlWsvqm/qge1fVjduzhISa/Zp
jwjPHvCM6ZD7BQgJz9/E/GtIDyRsSj3Svl5ItJtj+uru9cBdE2PXZH4vSeDY
20arfYAT6Z3e8axecnFxw49TXR/gU5X5vDu5H4kfvE0RnxSAsqvDMcduPmFk
jD7rihGA7RmZ5qlYPuEo6vFq7gigR67QPetXPqnm+rJy2wUA0hVVHindZOmu
yQwfy17Y4OU185n7e/LpoNH9bqYQPPrPvwn+2kkOXT/zqim+DzJ72WEzdrcT
SprBJ7l9UD/Fag2c005SXasZhWV9kH51Z/aqhjZSo6dpc3WkD4L1tqolbGgj
JndzqmzdRPD67PLxVrNWIn7e0lS28BMs6Ba9FM1pJv7CZYLign6IeWFYmrqk
jvR4/jOrlNsPoqNsieZftcS5I9qsvrcf8tnmIzq6tcSiVnRKqDsALqbKTVU/
1RCFoiw1ragBULG3LYphVhNOuIF1yN7PkFMpYVXI35BSTZ2UdWpfgMls07e/
84QoGUQa8S0GgVn/55MIdixUWyWsOLtpEAIiTazYlglw2e3W2gVOg5BMOVFO
zolAxT/ZsvvwIJAvj7SczqbC+Hex37ubgxD8udJ0tkcmfOa55DRSQ8DwsFzc
6lkIdRyjZa/rhsAywLBSze45xKnVGt/eJwFLB1UN7sVq8O7aRRTqRsFbq7Mr
JqcdTlREeh8zGoeOsKZ1bgF8KDqu4qxtK4c/T0q26boJ4PbpwwMrXRn4N9vd
qamzDy6kTzqOiJmo6OOuteZtPzBaevBFmALy6nNqfwkTw5JA39BdxjPwSH3B
vlWGX6FXmvyb8suZeCtkhRV5NAh2wkNnrp+YhaOXrkQMdg/Bjt54ExZLCdti
v+y2+XcYBt54R1TnKyOH4R+txpOAmXr7Apu9quiaByGbG0dACaRePMmPmLmw
vX84Swpbvrh/M3RRQziRFnP5wih0lB1gupuqY0FCbZyewzcoiS731JeqY4Zj
3+qZP4yB74ygnoYGDcz5GOJ8uXwM9p88XaKSqonn9R26+EdlsMLPpMHeaw4K
rc1neaqOQ6OGqXLQurmYKexKyno4Ds8LLqSZKmhhhvxW6cjWCTjNNHaoe6+F
pidKHHi9E6DEC9vqXzwPGaH7eO6hkyDMNkhMD9fGsUD+Knv5JCQu1VF86qKD
h3vll15HyyE+1bfKS18XbTje/KqZ38E9cU+DikgXNYxUk++f/Q5jG7Nk6a/m
49yHih6fJ7+DQLghtCxKD9We/pFtf2wKMtir5td7LcDHFdUyrmgK8i8Fqfst
Z2H5rdC2ZGMGRrns36YgZWHfc/sj7Z4MNOfdzo2qX4jaWiITpSQGcpal5ddv
08c4nrYPVjPw3OurnG1P9ZGdfship5yB2+e7ZNUsMsAzD/MLtFcycb1/1W71
Kwb4qn7LsIcnE9P1vBfVSQ1QUbd5z75rTFz05m7Sjt2GeHJ9UIrOCybGLy8z
bn5liLETFcsURUz0lSi+5RrTGL/GlX1jDoXeRcP6V67R6DRvQNHcmsIjF5wn
7RJoPPVD0ph42kHOxe9U/qDR/97LrjtAYbQ0KC4+iUa6N+b4nPUUFqyTTSTf
pDFTFtw6bEOhrHSqPTuPRo1786Pv21IY36xytbyKxo0v5z7UdKEwNfPowctc
GuUeojTutDMDG2y21tIYpHQ98NxvFD7Sih+vbaBRfeZZ6YArhTx3zYMtbTRC
CmNNqTuFRgIdm48CGveGmxUf2kfhyuIw1h0hjasPiNIWelFoealL5iOiMZKf
HdA6bXujmw/6B2gk7zZK2PspPHlYnzU0RGN40raf1XwpDLc6L/tbMv0vikor
n/Yl1Y+tgVIayzZ/kIT6UcgpzIwZG6Px0d7RwA8HKcyIUPR7Nk7j8sLHN2/8
TmGeo8+G8Ekab1ncfmR7iMJiw8oF1t9pnF9RQuTTfiVZIpuaonFCb+xJ0WEK
/wc13qzo
"]]}},
AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948],
Axes->True,
AxesLabel->{None, None},
AxesOrigin->{0, 0},
Method->{},
PlotRange->{{0, 10}, {-1.623796532045525, 2.3025850725858823`}},
PlotRangeClipping->True,
PlotRangePadding->{
Scaled[0.02],
Scaled[0.02]}]], "Output",
CellChangeTimes->{3.6112717778594217`*^9}]
}, Open ]]
},
WindowSize->{716, 833},
WindowMargins->{{Automatic, 214}, {Automatic, 26}},
FrontEndVersion->"9.0 for Microsoft Windows (64-bit) (January 25, 2013)",
StyleDefinitions->"Default.nb"
]
(* End of Notebook Content *)
(* Internal cache information *)
(*CellTagsOutline
CellTagsIndex->{}
*)
(*CellTagsIndex
CellTagsIndex->{}
*)
(*NotebookFileOutline
Notebook[{
Cell[CellGroupData[{
Cell[579, 22, 224, 6, 52, "Input"],
Cell[806, 30, 211, 6, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[1054, 41, 155, 3, 31, "Input"],
Cell[1212, 46, 130, 3, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[1379, 54, 137, 4, 31, "Input"],
Cell[1519, 60, 105, 2, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[1661, 67, 113, 3, 31, "Input"],
Cell[1777, 72, 90, 1, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[1904, 78, 102, 2, 31, "Input"],
Cell[2009, 82, 321, 8, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[2367, 95, 191, 4, 52, "Input"],
Cell[2561, 101, 131, 3, 31, "Output"]
}, Open ]],
Cell[2707, 107, 94, 1, 31, "Input"],
Cell[CellGroupData[{
Cell[2826, 112, 299, 8, 52, "Input"],
Cell[3128, 122, 3019, 57, 265, "Output"]
}, Open ]]
}
]
*)
(* End of internal cache information *)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
(* ::Package:: *)
(* Problem12.m *)
(* Author: William Woodruff *)
(* Problem: What is the value of the first triangle number to have over five hundred divisors? *)
Do[If[Length[Divisors[Binomial[i + 1, 2]]] > 500,
Print[Binomial[i + 1, 2]]; Break[]], {i, 1000000}]

272
samples/Nit/calculator.nit Normal file
View File

@@ -0,0 +1,272 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import gtk
class CalculatorContext
var result : nullable Float = null
var last_op : nullable Char = null
var current : nullable Float = null
var after_point : nullable Int = null
fun push_op( op : Char )
do
apply_last_op_if_any
if op == 'C' then
self.result = 0.0
last_op = null
else
last_op = op # store for next push_op
end
# prepare next current
after_point = null
current = null
end
fun push_digit( digit : Int )
do
var current = current
if current == null then current = 0.0
var after_point = after_point
if after_point == null then
current = current * 10.0 + digit.to_f
else
current = current + digit.to_f * 10.0.pow(after_point.to_f)
self.after_point -= 1
end
self.current = current
end
fun switch_to_decimals
do
if self.current == null then current = 0.0
if after_point != null then return
after_point = -1
end
fun apply_last_op_if_any
do
var op = last_op
var result = result
if result == null then result = 0.0
var current = current
if current == null then current = 0.0
if op == null then
result = current
else if op == '+' then
result = result + current
else if op == '-' then
result = result - current
else if op == '/' then
result = result / current
else if op == '*' then
result = result * current
end
self.result = result
self.current = null
end
end
class CalculatorGui
super GtkCallable
var win : GtkWindow
var container : GtkGrid
var lbl_disp : GtkLabel
var but_eq : GtkButton
var but_dot : GtkButton
var context = new CalculatorContext
redef fun signal( sender, user_data )
do
var after_point = context.after_point
if after_point == null then
after_point = 0
else
after_point = (after_point.abs)
end
if user_data isa Char then # is an operation
var c = user_data
if c == '.' then
but_dot.sensitive= false
context.switch_to_decimals
lbl_disp.text = "{context.current.to_i}."
else
but_dot.sensitive= true
context.push_op( c )
var s = context.result.to_precision_native(6)
var index : nullable Int = null
for i in s.length.times do
var chiffre = s.chars[i]
if chiffre == '0' and index == null then
index = i
else if chiffre != '0' then
index = null
end
end
if index != null then
s = s.substring(0, index)
if s.chars[s.length-1] == ',' then s = s.substring(0, s.length-1)
end
lbl_disp.text = s
end
else if user_data isa Int then # is a number
var n = user_data
context.push_digit( n )
lbl_disp.text = context.current.to_precision_native(after_point)
end
end
init
do
init_gtk
win = new GtkWindow( 0 )
container = new GtkGrid(5,5,true)
win.add( container )
lbl_disp = new GtkLabel( "_" )
container.attach( lbl_disp, 0, 0, 5, 1 )
# digits
for n in [0..9] do
var but = new GtkButton.with_label( n.to_s )
but.request_size( 64, 64 )
but.signal_connect( "clicked", self, n )
if n == 0 then
container.attach( but, 0, 4, 1, 1 )
else container.attach( but, (n-1)%3, 3-(n-1)/3, 1, 1 )
end
# operators
var r = 1
for op in ['+', '-', '*', '/' ] do
var but = new GtkButton.with_label( op.to_s )
but.request_size( 64, 64 )
but.signal_connect( "clicked", self, op )
container.attach( but, 3, r, 1, 1 )
r+=1
end
# =
but_eq = new GtkButton.with_label( "=" )
but_eq.request_size( 64, 64 )
but_eq.signal_connect( "clicked", self, '=' )
container.attach( but_eq, 4, 3, 1, 2 )
# .
but_dot = new GtkButton.with_label( "." )
but_dot.request_size( 64, 64 )
but_dot.signal_connect( "clicked", self, '.' )
container.attach( but_dot, 1, 4, 1, 1 )
#C
var but_c = new GtkButton.with_label( "C" )
but_c.request_size( 64, 64 )
but_c.signal_connect("clicked", self, 'C')
container.attach( but_c, 2, 4, 1, 1 )
win.show_all
end
end
# context tests
var context = new CalculatorContext
context.push_digit( 1 )
context.push_digit( 2 )
context.push_op( '+' )
context.push_digit( 3 )
context.push_op( '*' )
context.push_digit( 2 )
context.push_op( '=' )
var r = context.result.to_precision( 2 )
assert r == "30.00" else print r
context = new CalculatorContext
context.push_digit( 1 )
context.push_digit( 4 )
context.switch_to_decimals
context.push_digit( 1 )
context.push_op( '*' )
context.push_digit( 3 )
context.push_op( '=' )
r = context.result.to_precision( 2 )
assert r == "42.30" else print r
context.push_op( '+' )
context.push_digit( 1 )
context.push_digit( 1 )
context.push_op( '=' )
r = context.result.to_precision( 2 )
assert r == "53.30" else print r
context = new CalculatorContext
context.push_digit( 4 )
context.push_digit( 2 )
context.switch_to_decimals
context.push_digit( 3 )
context.push_op( '/' )
context.push_digit( 3 )
context.push_op( '=' )
r = context.result.to_precision( 2 )
assert r == "14.10" else print r
#test multiple decimals
context = new CalculatorContext
context.push_digit( 5 )
context.push_digit( 0 )
context.switch_to_decimals
context.push_digit( 1 )
context.push_digit( 2 )
context.push_digit( 3 )
context.push_op( '+' )
context.push_digit( 1 )
context.push_op( '=' )
r = context.result.to_precision( 3 )
assert r == "51.123" else print r
#test 'C' button
context = new CalculatorContext
context.push_digit( 1 )
context.push_digit( 0 )
context.push_op( '+' )
context.push_digit( 1 )
context.push_digit( 0 )
context.push_op( '=' )
context.push_op( 'C' )
r = context.result.to_precision( 1 )
assert r == "0.0" else print r
# graphical application
if "NIT_TESTING".environ != "true" then
var app = new CalculatorGui
run_gtk
end

View File

@@ -0,0 +1,45 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This sample has been implemented to show you how simple is it to play
# with native callbacks (C) through an high level with NIT program.
module callback_chimpanze
import callback_monkey
class Chimpanze
super MonkeyActionCallable
fun create
do
var monkey = new Monkey
print "Hum, I'm sleeping ..."
# Invoking method which will take some time to compute, and
# will be back in wokeUp method with information.
# - Callback method defined in MonkeyActionCallable Interface
monkey.wokeUpAction(self, "Hey, I'm awake.")
end
# Inherit callback method, defined by MonkeyActionCallable interface
# - Back of wokeUpAction method
redef fun wokeUp( sender:Monkey, message:Object )
do
print message
end
end
var m = new Chimpanze
m.create

View File

@@ -0,0 +1,92 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This sample has been implemented to show you how simple is it to play
# with native callbacks (C) through an high level with NIT program.
module callback_monkey
in "C header" `{
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int id;
int age;
} CMonkey;
typedef struct {
MonkeyActionCallable toCall;
Object message;
} MonkeyAction;
`}
in "C body" `{
// Method which reproduce a callback answer
// Please note that a function pointer is only used to reproduce the callback
void cbMonkey(CMonkey *mkey, void callbackFunc(CMonkey*, MonkeyAction*), MonkeyAction *data)
{
sleep(2);
callbackFunc( mkey, data );
}
// Back of background treatment, will be redirected to callback function
void nit_monkey_callback_func( CMonkey *mkey, MonkeyAction *data )
{
// To call a your method, the signature must be written like this :
// <Interface Name>_<Method>...
MonkeyActionCallable_wokeUp( data->toCall, mkey, data->message );
}
`}
# Implementable interface to get callback in defined methods
interface MonkeyActionCallable
fun wokeUp( sender:Monkey, message: Object) is abstract
end
# Defining my object type Monkey, which is, in a low level, a pointer to a C struct (CMonkey)
extern class Monkey `{ CMonkey * `}
new `{
CMonkey *monkey = malloc( sizeof(CMonkey) );
monkey->age = 10;
monkey->id = 1;
return monkey;
`}
# Object method which will get a callback in wokeUp method, defined in MonkeyActionCallable interface
# Must be defined as Nit/C method because of C call inside
fun wokeUpAction( toCall: MonkeyActionCallable, message: Object ) is extern import MonkeyActionCallable.wokeUp `{
// Allocating memory to keep reference of received parameters :
// - Object receiver
// - Message
MonkeyAction *data = malloc( sizeof(MonkeyAction) );
// Incrementing reference counter to prevent from releasing
MonkeyActionCallable_incr_ref( toCall );
Object_incr_ref( message );
data->toCall = toCall;
data->message = message;
// Calling method which reproduce a callback by passing :
// - Receiver
// - Function pointer to object return method
// - Datas
cbMonkey( recv, &nit_monkey_callback_func, data );
`}
end

View File

@@ -0,0 +1,167 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Implementation of circular lists
# This example shows the usage of generics and somewhat a specialisation of collections.
module circular_list
# Sequences of elements implemented with a double-linked circular list
class CircularList[E]
# Like standard Array or LinkedList, CircularList is a Sequence.
super Sequence[E]
# The first node of the list if any
# The special case of an empty list is handled by a null node
private var node: nullable CLNode[E] = null
redef fun iterator do return new CircularListIterator[E](self)
redef fun first do return self.node.item
redef fun push(e)
do
var new_node = new CLNode[E](e)
var n = self.node
if n == null then
# the first node
self.node = new_node
else
# not the first one, so attach nodes correctly.
var old_last_node = n.prev
new_node.next = n
new_node.prev = old_last_node
old_last_node.next = new_node
n.prev = new_node
end
end
redef fun pop
do
var n = self.node
assert n != null
var prev = n.prev
if prev == n then
# the only node
self.node = null
return n.item
end
# not the only one do detach nodes correctly.
var prev_prev = prev.prev
n.prev = prev_prev
prev_prev.next = n
return prev.item
end
redef fun unshift(e)
do
# Circularity has benefits.
push(e)
self.node = self.node.prev
end
redef fun shift
do
# Circularity has benefits.
self.node = self.node.next
return self.pop
end
# Move the first at the last position, the second at the first, etc.
fun rotate
do
var n = self.node
if n == null then return
self.node = n.next
end
# Sort the list using the Josephus algorithm.
fun josephus(step: Int)
do
var res = new CircularList[E]
while not self.is_empty do
# count 'step'
for i in [1..step[ do self.rotate
# kill
var x = self.shift
res.add(x)
end
self.node = res.node
end
end
# Nodes of a CircularList
private class CLNode[E]
# The current item
var item: E
# The next item in the circular list.
# Because of circularity, there is always a next;
# so by default let it be self
var next: CLNode[E] = self
# The previous item in the circular list.
# Coherence between next and previous nodes has to be maintained by the
# circular list.
var prev: CLNode[E] = self
end
# An iterator of a CircularList.
private class CircularListIterator[E]
super IndexedIterator[E]
redef var index: Int
# The current node pointed.
# Is null if the list is empty.
var node: nullable CLNode[E]
# The list iterated.
var list: CircularList[E]
redef fun is_ok
do
# Empty lists are not OK.
# Pointing again the first node is not OK.
return self.node != null and (self.index == 0 or self.node != self.list.node)
end
redef fun next
do
self.node = self.node.next
self.index += 1
end
redef fun item do return self.node.item
init(list: CircularList[E])
do
self.node = list.node
self.list = list
self.index = 0
end
end
var i = new CircularList[Int]
i.add_all([1, 2, 3, 4, 5, 6, 7])
print i.first
print i.join(":")
i.push(8)
print i.shift
print i.pop
i.unshift(0)
print i.join(":")
i.josephus(3)
print i.join(":")

78
samples/Nit/clock.nit Normal file
View File

@@ -0,0 +1,78 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This module provide a simple wall clock.
# It is an example of getters and setters.
# A beefed-up module is available in clock_more
module clock
# A simple wall clock with 60 minutes and 12 hours.
class Clock
# total number of minutes from 0 to 719
var total_minutes: Int
# Note: only the read acces is public, the write access is private.
# number of minutes in the current hour (from 0 to 59)
fun minutes: Int do return self.total_minutes % 60
# set the number of minutes in the current hour.
# if m < 0 or m >= 60, the hour will be changed accordinlgy
fun minutes=(m: Int) do self.total_minutes = self.hours * 60 + m
# number of hours (from 0 to 11)
fun hours: Int do return self.total_minutes / 60
# set the number of hours
# the minutes will not be updated
fun hours=(h: Int) do self.total_minutes = h * 60 + minutes
# the position of the hour arrow in the [0..60[ interval
fun hour_pos: Int do return total_minutes / 12
# replace the arrow of hours (from 0 to 59).
# the hours and the minutes will be updated.
fun hour_pos=(h: Int) do self.total_minutes = h * 12
redef fun to_s do return "{hours}:{minutes}"
fun reset(hours, minutes: Int) do self.total_minutes = hours*60 + minutes
init(hours, minutes: Int) do self.reset(hours, minutes)
redef fun ==(o)
do
# Note: o is a nullable Object, a type test is required
# Thanks to adaptive typing, there is no downcast
# i.e. the code is safe!
return o isa Clock and self.total_minutes == o.total_minutes
end
end
var c = new Clock(10,50)
print "It's {c} o'clock."
c.minutes += 22
print "Now it's {c} o'clock."
print "The short arrow in on the {c.hour_pos/5} and the long arrow in on the {c.minutes/5}."
c.hours -= 2
print "Now it's {c} o'clock."
var c2 = new Clock(9, 11)
print "It's {c2} on the second clock."
print "The two clocks are synchronized: {c == c2}."
c2.minutes += 1
print "It's now {c2} on the second clock."
print "The two clocks are synchronized: {c == c2}."

View File

@@ -0,0 +1,60 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This module beef up the clock module by allowing a clock to be comparable.
# It show the usage of class refinement
module clock_more
import clock
redef class Clock
# Clock are now comparable
super Comparable
# Comparaison of a clock make only sense with an other clock
redef type OTHER: Clock
redef fun <(o)
do
# Note: < is the only abstract method of Comparable.
# All other operators and methods rely on < and ==.
return self.total_minutes < o.total_minutes
end
end
var c1 = new Clock(8, 12)
var c2 = new Clock(8, 13)
var c3 = new Clock(9, 13)
print "{c1}<{c2}? {c1<c2}"
print "{c1}<={c2}? {c1<=c2}"
print "{c1}>{c2}? {c1>c2}"
print "{c1}>={c2}? {c1>=c2}"
print "{c1}<=>{c2}? {c1<=>c2}"
print "{c1},{c2}? max={c1.max(c2)} min={c1.min(c2)}"
print "{c1}.is_between({c2}, {c3})? {c1.is_between(c2, c3)}"
print "{c2}.is_between({c1}, {c3})? {c2.is_between(c1, c3)}"
print "-"
c1.minutes += 1
print "{c1}<{c2}? {c1<c2}"
print "{c1}<={c2}? {c1<=c2}"
print "{c1}>{c2}? {c1>c2}"
print "{c1}>={c2}? {c1>=c2}"
print "{c1}<=>{c2}? {c1<=>c2}"
print "{c1},{c2}? max={c1.max(c2)} min={c1.min(c2)}"
print "{c1}.is_between({c2}, {c3})? {c1.is_between(c2, c3)}"
print "{c2}.is_between({c1}, {c3})? {c2.is_between(c1, c3)}"

113
samples/Nit/curl_http.nit Normal file
View File

@@ -0,0 +1,113 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Sample of the Curl module.
module curl_http
import curl
# Small class to represent an Http Fetcher
class MyHttpFetcher
super CurlCallbacks
var curl: Curl
var our_body: String = ""
init(curl: Curl) do self.curl = curl
# Release curl object
fun destroy do self.curl.destroy
# Header callback
redef fun header_callback(line: String) do
# We keep this callback silent for testing purposes
#if not line.has_prefix("Date:") then print "Header_callback : {line}"
end
# Body callback
redef fun body_callback(line: String) do self.our_body = "{self.our_body}{line}"
# Stream callback - Cf : No one is registered
redef fun stream_callback(buffer: String, size: Int, count: Int) do print "Stream_callback : {buffer} - {size} - {count}"
end
# Program
if args.length < 2 then
print "Usage: curl_http <method wished [POST, GET, GET_FILE]> <target url>"
else
var curl = new Curl
var url = args[1]
var request = new CurlHTTPRequest(url, curl)
# HTTP Get Request
if args[0] == "GET" then
request.verbose = false
var getResponse = request.execute
if getResponse isa CurlResponseSuccess then
print "Status code : {getResponse.status_code}"
print "Body : {getResponse.body_str}"
else if getResponse isa CurlResponseFailed then
print "Error code : {getResponse.error_code}"
print "Error msg : {getResponse.error_msg}"
end
# HTTP Post Request
else if args[0] == "POST" then
var myHttpFetcher = new MyHttpFetcher(curl)
request.delegate = myHttpFetcher
var postDatas = new HeaderMap
postDatas["Bugs Bunny"] = "Daffy Duck"
postDatas["Batman"] = "Robin likes special characters @#ùà!è§'(\"é&://,;<>∞~*"
postDatas["Batman"] = "Yes you can set multiple identical keys, but APACHE will consider only once, the last one"
request.datas = postDatas
request.verbose = false
var postResponse = request.execute
print "Our body from the callback : {myHttpFetcher.our_body}"
if postResponse isa CurlResponseSuccess then
print "*** Answer ***"
print "Status code : {postResponse.status_code}"
print "Body should be empty, because we decided to manage callbacks : {postResponse.body_str.length}"
else if postResponse isa CurlResponseFailed then
print "Error code : {postResponse.error_code}"
print "Error msg : {postResponse.error_msg}"
end
# HTTP Get to file Request
else if args[0] == "GET_FILE" then
var headers = new HeaderMap
headers["Accept"] = "Moo"
request.headers = headers
request.verbose = false
var downloadResponse = request.download_to_file(null)
if downloadResponse isa CurlFileResponseSuccess then
print "*** Answer ***"
print "Status code : {downloadResponse.status_code}"
print "Size downloaded : {downloadResponse.size_download}"
else if downloadResponse isa CurlResponseFailed then
print "Error code : {downloadResponse.error_code}"
print "Error msg : {downloadResponse.error_msg}"
end
# Program logic
else
print "Usage : Method[POST, GET, GET_FILE]"
end
end

59
samples/Nit/curl_mail.nit Normal file
View File

@@ -0,0 +1,59 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Mail sender sample using the Curl module
module curl_mail
import curl
var curl = new Curl
var mail_request = new CurlMailRequest(curl)
# Networks
var response = mail_request.set_outgoing_server("smtps://smtp.example.org:465", "user@example.org", "mypassword")
if response isa CurlResponseFailed then
print "Error code : {response.error_code}"
print "Error msg : {response.error_msg}"
end
# Headers
mail_request.from = "Billy Bob"
mail_request.to = ["user@example.org"]
mail_request.cc = ["bob@example.org"]
mail_request.bcc = null
var headers_body = new HeaderMap
headers_body["Content-Type:"] = "text/html; charset=\"UTF-8\""
headers_body["Content-Transfer-Encoding:"] = "quoted-printable"
mail_request.headers_body = headers_body
# Content
mail_request.body = "<h1>Here you can write HTML stuff.</h1>"
mail_request.subject = "Hello From My Nit Program"
# Others
mail_request.verbose = false
# Send mail
response = mail_request.execute
if response isa CurlResponseFailed then
print "Error code : {response.error_code}"
print "Error msg : {response.error_msg}"
else if response isa CurlMailResponseSuccess then
print "Mail Sent"
else
print "Unknown Curl Response type"
end

View File

@@ -0,0 +1,243 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Draws an arithmetic operation to the terminal
module draw_operation
redef enum Int
fun n_chars: Int `{
int c;
if ( abs(recv) >= 10 )
c = 1+(int)log10f( (float)abs(recv) );
else
c = 1;
if ( recv < 0 ) c ++;
return c;
`}
end
redef enum Char
fun as_operator(a, b: Int): Int
do
if self == '+' then return a + b
if self == '-' then return a - b
if self == '*' then return a * b
if self == '/' then return a / b
if self == '%' then return a % b
abort
end
fun override_dispc: Bool
do
return self == '+' or self == '-' or self == '*' or self == '/' or self == '%'
end
fun lines(s: Int): Array[Line]
do
if self == '+' then
return [new Line(new P(0,s/2),1,0,s), new Line(new P(s/2,1),0,1,s-2)]
else if self == '-' then
return [new Line(new P(0,s/2),1,0,s)]
else if self == '*' then
var lines = new Array[Line]
for y in [1..s-1[ do
lines.add( new Line(new P(1,y), 1,0,s-2) )
end
return lines
else if self == '/' then
return [new Line(new P(s-1,0), -1,1, s )]
else if self == '%' then
var q4 = s/4
var lines = [new Line(new P(s-1,0),-1,1,s)]
for l in [0..q4[ do
lines.append([ new Line( new P(0,l), 1,0,q4), new Line( new P(s-1,s-1-l), -1,0,q4) ])
end
return lines
else if self == '1' then
return [new Line(new P(s/2,0), 0,1,s),new Line(new P(0,s-1),1,0,s),
new Line( new P(s/2,0),-1,1,s/2)]
else if self == '2' then
return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s/2),
new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 0,1,s/2),
new Line( new P(0,s/2), 1,0,s)]
else if self == '3' then
return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 1,0,s)]
else if self == '4' then
return [new Line(new P(s-1,0),0,1,s), new Line( new P(0,0), 0,1,s/2),
new Line( new P(0,s/2), 1,0,s)]
else if self == '5' then
return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2),
new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2),
new Line( new P(0,s/2), 1,0,s)]
else if self == '6' then
return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2),
new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s),
new Line( new P(0,s/2), 1,0,s)]
else if self == '7' then
var tl = new P(0,0)
var tr = new P(s-1,0)
return [new Line(tl, 1,0,s), new Line(tr,-1,1,s)]
else if self == '8' then
return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s),
new Line( new P(0,s/2), 1,0,s)]
else if self == '9' then
return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2),
new Line( new P(0,s/2), 1,0,s)]
else if self == '0' then
return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s)]
end
return new Array[Line]
end
end
class P
var x : Int
var y : Int
end
redef class String
# hack is to support a bug in the evaluation software
fun draw(dispc: Char, size, gap: Int, hack: Bool)
do
var w = size * length +(length-1)*gap
var h = size
var map = new Array[Array[Char]]
for x in [0..w[ do
map[x] = new Array[Char].filled_with( ' ', h )
end
var ci = 0
for c in self.chars do
var local_dispc
if c.override_dispc then
local_dispc = c
else
local_dispc = dispc
end
var lines = c.lines( size )
for line in lines do
var x = line.o.x+ci*size
x += ci*gap
var y = line.o.y
for s in [0..line.len[ do
assert map.length > x and map[x].length > y else print "setting {x},{y} as {local_dispc}"
map[x][y] = local_dispc
x += line.step_x
y += line.step_y
end
end
ci += 1
end
if hack then
for c in [0..size[ do
map[c][0] = map[map.length-size+c][0]
map[map.length-size+c][0] = ' '
end
end
for y in [0..h[ do
for x in [0..w[ do
printn map[x][y]
end
print ""
end
end
end
class Line
var o : P
var step_x : Int
var step_y : Int
var len : Int
end
var a
var b
var op_char
var disp_char
var disp_size
var disp_gap
if "NIT_TESTING".environ == "true" then
a = 567
b = 13
op_char = '*'
disp_char = 'O'
disp_size = 8
disp_gap = 1
else
printn "Left operand: "
a = gets.to_i
printn "Right operand: "
b = gets.to_i
printn "Operator (+, -, *, /, %): "
op_char = gets.chars[0]
printn "Char to display: "
disp_char = gets.chars[0]
printn "Size of text: "
disp_size = gets.to_i
printn "Space between digits: "
disp_gap = gets.to_i
end
var result = op_char.as_operator( a, b )
var len_a = a.n_chars
var len_b = b.n_chars
var len_res = result.n_chars
var max_len = len_a.max( len_b.max( len_res ) ) + 1
# draw first line
var d = max_len - len_a
var line_a = ""
for i in [0..d[ do line_a += " "
line_a += a.to_s
line_a.draw( disp_char, disp_size, disp_gap, false )
print ""
# draw second line
d = max_len - len_b-1
var line_b = op_char.to_s
for i in [0..d[ do line_b += " "
line_b += b.to_s
line_b.draw( disp_char, disp_size, disp_gap, false )
# draw -----
print ""
for i in [0..disp_size*max_len+(max_len-1)*disp_gap] do
printn "_"
end
print ""
print ""
# draw result
d = max_len - len_res
var line_res = ""
for i in [0..d[ do line_res += " "
line_res += result.to_s
line_res.draw( disp_char, disp_size, disp_gap, false )

View File

@@ -0,0 +1,46 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Example using the privileges module to drop privileges from root
module drop_privileges
import privileges
# basic command line options
var opts = new OptionContext
var opt_ug = new OptionUserAndGroup.for_dropping_privileges
opt_ug.mandatory = true
opts.add_option(opt_ug)
# parse and check command line options
opts.parse(args)
if not opts.errors.is_empty then
print opts.errors
print "Usage: drop_privileges [options]"
opts.usage
exit 1
end
# original user
print "before {sys.uid}:{sys.gid}"
# make the switch
var user_group = opt_ug.value
assert user_group != null
user_group.drop_privileges
# final user
print "after {sys.uid}:{sys.egid}"

View File

@@ -0,0 +1,69 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This module illustrates some uses of the FFI, specifically
# how to use extern methods. Which means to implement a Nit method in C.
module extern_methods
redef enum Int
# Returns self'th fibonnaci number
# implemented here in C for optimization purposes
fun fib : Int import fib `{
if ( recv < 2 )
return recv;
else
return Int_fib( recv-1 ) + Int_fib( recv-2 );
`}
# System call to sleep for "self" seconds
fun sleep `{
sleep( recv );
`}
# Return atan2l( self, x ) from libmath
fun atan_with( x : Int ) : Float `{
return atan2( recv, x );
`}
# This method callback to Nit methods from C code
# It will use from C code:
# * the local fib method
# * the + operator, a method of Int
# * to_s, a method of all objects
# * String.to_cstring, a method of String to return an equivalent char*
fun foo import fib, +, to_s, String.to_cstring `{
long recv_fib = Int_fib( recv );
long recv_plus_fib = Int__plus( recv, recv_fib );
String nit_string = Int_to_s( recv_plus_fib );
char *c_string = String_to_cstring( nit_string );
printf( "from C: self + fib(self) = %s\n", c_string );
`}
# Equivalent to foo but written in pure Nit
fun bar do print "from Nit: self + fib(self) = {self+self.fib}"
end
print 12.fib
print "sleeping 1 second..."
1.sleep
print 100.atan_with( 200 )
8.foo
8.bar

43
samples/Nit/fibonacci.nit Normal file
View File

@@ -0,0 +1,43 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2004-2008 Jean Privat <jean@pryen.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# A simple exemple of refinement where a method is added to the integer class.
module fibonacci
redef class Int
# Calculate the self-th element of the fibonacci sequence.
fun fibonacci: Int
do
if self < 2 then
return 1
else
return (self-2).fibonacci + (self-1).fibonacci
end
end
end
# Print usage and exit.
fun usage
do
print "Usage: fibonnaci <integer>"
exit 0
end
# Main part
if args.length != 1 then
usage
end
print args.first.to_i.fibonacci

View File

@@ -0,0 +1 @@
print "hello world"

105
samples/Nit/html_page.nit Normal file
View File

@@ -0,0 +1,105 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import html
class NitHomepage
super HTMLPage
redef fun head do
add("meta").attr("charset", "utf-8")
add("title").text("Nit")
add("link").attr("rel", "icon").attr("href", "http://nitlanguage.org/favicon.ico").attr("type", "image/x-icon")
add("link").attr("rel", "stylesheet").attr("href", "http://nitlanguage.org/style.css").attr("type", "text/css")
add("link").attr("rel", "stylesheet").attr("href", "http://nitlanguage.org/local.css").attr("type", "text/css")
end
redef fun body do
open("article").add_class("page")
open("section").add_class("pageheader")
add_html("<a id='toptitle_first' class='toptitle'>the</a><a id='toptitle_second' class='toptitle' href=''>Nit</a><a id='toptitle_third' class='toptitle' href=''>Programming Language</a>")
open("header").add_class("header")
open("div").add_class("topsubtitle")
add("p").text("A Fun Language for Serious Programming")
close("div")
close("header")
close("section")
open("div").attr("id", "pagebody")
open("section").attr("id", "content")
add("h1").text("# What is Nit?")
add("p").text("Nit is an object-oriented programming language. The goal of Nit is to propose a robust statically typed programming language where structure is not a pain.")
add("p").text("So, what does the famous hello world program look like, in Nit?")
add_html("<pre><tt><span class='normal'>print </span><span class='string'>'Hello, World!'</span></tt></pre>")
add("h1").text("# Feature Highlights")
add("h2").text("Usability")
add("p").text("Nit's goal is to be usable by real programmers for real projects")
open("ul")
open("li")
add("a").attr("href", "http://en.wikipedia.org/wiki/KISS_principle").text("KISS principle")
close("li")
add("li").text("Script-like language without verbosity nor cryptic statements")
add("li").text("Painless static types: static typing should help programmers")
add("li").text("Efficient development, efficient execution, efficient evolution.")
close("ul")
add("h2").text("Robustness")
add("p").text("Nit will help you to write bug-free programs")
open("ul")
add("li").text("Strong static typing")
add("li").text("No more NullPointerException")
close("ul")
add("h2").text("Object-Oriented")
add("p").text("Nit's guideline is to follow the most powerful OO principles")
open("ul")
open("li")
add("a").attr("href", "./everything_is_an_object/").text("Everything is an object")
close("li")
open("li")
add("a").attr("href", "./multiple_inheritance/").text("Multiple inheritance")
close("li")
open("li")
add("a").attr("href", "./refinement/").text("Open classes")
close("li")
open("li")
add("a").attr("href", "./virtual_types/").text("Virtual types")
close("li")
close("ul")
add("h1").text("# Getting Started")
add("p").text("Get Nit from its Git repository:")
add_html("<pre><code>$ git clone http://nitlanguage.org/nit.git</code></pre>")
add("p").text("Build the compiler (may be long):")
add_html("<pre><code>$ cd nit\n")
add_html("$ make</code></pre>")
add("p").text("Compile a program:")
add_html("<pre><code>$ bin/nitc examples/hello_world.nit</code></pre>")
add("p").text("Execute the program:")
add_html("<pre><code>$ ./hello_world</code></pre>")
close("section")
close("div")
close("article")
end
end
var page = new NitHomepage
page.write_to stdout
page.write_to_file("nit.html")

100
samples/Nit/int_stack.nit Normal file
View File

@@ -0,0 +1,100 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# An example that defines and uses stacks of integers.
# The implementation is done with a simple linked list.
# It features: free constructors, nullable types and some adaptive typing.
module int_stack
# A stack of integer implemented by a simple linked list.
# Note that this is only a toy class since a real linked list will gain to use
# generics and extends interfaces, like Collection, from the standard library.
class IntStack
# The head node of the list.
# Null means that the stack is empty.
private var head: nullable ISNode = null
# Add a new integer in the stack.
fun push(val: Int)
do
self.head = new ISNode(val, self.head)
end
# Remove and return the last pushed integer.
# Return null if the stack is empty.
fun pop: nullable Int
do
var head = self.head
if head == null then return null
# Note: the followings are statically safe because of the
# previous 'if'.
var val = head.val
self.head = head.next
return val
end
# Return the sum of all integers of the stack.
# Return 0 if the stack is empty.
fun sumall: Int
do
var sum = 0
var cur = self.head
while cur != null do
# Note: the followings are statically safe because of
# the condition of the 'while'.
sum += cur.val
cur = cur.next
end
return sum
end
# Note: Because all attributes have a default value, a free constructor
# "init()" is implicitly defined.
end
# A node of a IntStack
private class ISNode
# The integer value stored in the node.
var val: Int
# The next node, if any.
var next: nullable ISNode
# Note: A free constructor "init(val: Int, next: nullable ISNode)" is
# implicitly defined.
end
var l = new IntStack
l.push(1)
l.push(2)
l.push(3)
print l.sumall
# Note: the 'for' control structure cannot be used on IntStack in its current state.
# It requires a more advanced topic.
# However, why not using the 'loop' control structure?
loop
var i = l.pop
if i == null then break
# The following is statically safe because of the previous 'if'.
print i * 10
end
# Note: 'or else' is used to give an alternative of a null expression.
l.push(5)
print l.pop or else 0 # l.pop gives 5, so print 5
print l.pop or else 0 # l.pop gives null, so print the alternative: 0

View File

@@ -0,0 +1,193 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Basic example of OpenGL ES 2.0 usage from the book OpenGL ES 2.0 Programming Guide.
#
# Code reference:
# https://code.google.com/p/opengles-book-samples/source/browse/trunk/LinuxX11/Chapter_2/Hello_Triangle/Hello_Triangle.c
module opengles2_hello_triangle
import glesv2
import egl
import mnit_linux # for sdl
import x11
if "NIT_TESTING".environ == "true" then exit(0)
var window_width = 800
var window_height = 600
#
## SDL
#
var sdl_display = new SDLDisplay(window_width, window_height)
var sdl_wm_info = new SDLSystemWindowManagerInfo
var x11_window_handle = sdl_wm_info.x11_window_handle
#
## X11
#
var x_display = x_open_default_display
assert x_display != 0 else print "x11 fail"
#
## EGL
#
var egl_display = new EGLDisplay(x_display)
assert egl_display.is_valid else print "EGL display is not valid"
egl_display.initialize
print "EGL version: {egl_display.version}"
print "EGL vendor: {egl_display.vendor}"
print "EGL extensions: {egl_display.extensions.join(", ")}"
print "EGL client APIs: {egl_display.client_apis.join(", ")}"
assert egl_display.is_valid else print egl_display.error
var config_chooser = new EGLConfigChooser
#config_chooser.surface_type_egl
config_chooser.blue_size = 8
config_chooser.green_size = 8
config_chooser.red_size = 8
#config_chooser.alpha_size = 8
#config_chooser.depth_size = 8
#config_chooser.stencil_size = 8
#config_chooser.sample_buffers = 1
config_chooser.close
var configs = config_chooser.choose(egl_display)
assert configs != null else print "choosing config failed: {egl_display.error}"
assert not configs.is_empty else print "no EGL config"
print "{configs.length} EGL configs available"
for config in configs do
var attribs = config.attribs(egl_display)
print "* caveats: {attribs.caveat}"
print " conformant to: {attribs.conformant}"
print " size of RGBA: {attribs.red_size} {attribs.green_size} {attribs.blue_size} {attribs.alpha_size}"
print " buffer, depth, stencil: {attribs.buffer_size} {attribs.depth_size} {attribs.stencil_size}"
end
var config = configs.first
var format = config.attribs(egl_display).native_visual_id
# TODO android part
# Opengles1Display_midway_init(recv, format);
var surface = egl_display.create_window_surface(config, x11_window_handle, [0])
assert surface.is_ok else print egl_display.error
var context = egl_display.create_context(config)
assert context.is_ok else print egl_display.error
var make_current_res = egl_display.make_current(surface, surface, context)
assert make_current_res
var width = surface.attribs(egl_display).width
var height = surface.attribs(egl_display).height
print "Width: {width}"
print "Height: {height}"
assert egl_bind_opengl_es_api else print "eglBingAPI failed: {egl_display.error}"
#
## GLESv2
#
print "Can compile shaders? {gl_shader_compiler}"
assert_no_gl_error
assert gl_shader_compiler else print "Cannot compile shaders"
# gl program
print gl_error.to_s
var program = new GLProgram
if not program.is_ok then
print "Program is not ok: {gl_error.to_s}\nLog:"
print program.info_log
abort
end
assert_no_gl_error
# vertex shader
var vertex_shader = new GLVertexShader
assert vertex_shader.is_ok else print "Vertex shader is not ok: {gl_error}"
vertex_shader.source = """
attribute vec4 vPosition;
void main()
{
gl_Position = vPosition;
} """
vertex_shader.compile
assert vertex_shader.is_compiled else print "Vertex shader compilation failed with: {vertex_shader.info_log} {program.info_log}"
assert_no_gl_error
# fragment shader
var fragment_shader = new GLFragmentShader
assert fragment_shader.is_ok else print "Fragment shader is not ok: {gl_error}"
fragment_shader.source = """
precision mediump float;
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
"""
fragment_shader.compile
assert fragment_shader.is_compiled else print "Fragment shader compilation failed with: {fragment_shader.info_log}"
assert_no_gl_error
program.attach_shader vertex_shader
program.attach_shader fragment_shader
program.bind_attrib_location(0, "vPosition")
program.link
assert program.is_linked else print "Linking failed: {program.info_log}"
assert_no_gl_error
# draw!
var vertices = [0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0]
var vertex_array = new VertexArray(0, 3, vertices)
vertex_array.attrib_pointer
gl_clear_color(0.5, 0.0, 0.5, 1.0)
for i in [0..10000[ do
printn "."
assert_no_gl_error
gl_viewport(0, 0, width, height)
gl_clear_color_buffer
program.use
vertex_array.enable
vertex_array.draw_arrays_triangles
egl_display.swap_buffers(surface)
end
# delete
program.delete
vertex_shader.delete
fragment_shader.delete
#
## EGL
#
# close
egl_display.make_current(new EGLSurface.none, new EGLSurface.none, new EGLContext.none)
egl_display.destroy_context(context)
egl_display.destroy_surface(surface)
#
## SDL
#
# close
sdl_display.destroy

View File

@@ -0,0 +1,22 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2004-2008 Jean Privat <jean@pryen.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# How to print arguments of the command line.
module print_arguments
for a in args do
print a
end

View File

@@ -0,0 +1,48 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2004-2008 Jean Privat <jean@pryen.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# A procedural program (without explicit class definition).
# This program manipulates arrays of integers.
module procedural_array
# The sum of the elements of `a'.
# Uses a 'for' control structure.
fun array_sum(a: Array[Int]): Int
do
var sum = 0
for i in a do
sum = sum + i
end
return sum
end
# The sum of the elements of `a' (alternative version).
# Uses a 'while' control structure.
fun array_sum_alt(a: Array[Int]): Int
do
var sum = 0
var i = 0
while i < a.length do
sum = sum + a[i]
i = i + 1
end
return sum
end
# The main part of the program.
var a = [10, 5, 8, 9]
print(array_sum(a))
print(array_sum_alt(a))

View File

@@ -0,0 +1,38 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Client sample using the Socket module which connect to the server sample.
module socket_client
import socket
if args.length < 2 then
print "Usage : socket_client <host> <port>"
return
end
var s = new Socket.client(args[0], args[1].to_i)
print "[HOST ADDRESS] : {s.address}"
print "[HOST] : {s.host}"
print "[PORT] : {s.port}"
print "Connecting ... {s.connected}"
if s.connected then
print "Writing ... Hello server !"
s.write("Hello server !")
print "[Response from server] : {s.read(100)}"
print "Closing ..."
s.close
end

View File

@@ -0,0 +1,52 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Server sample using the Socket module which allow client to connect
module socket_server
import socket
if args.is_empty then
print "Usage : socket_server <port>"
return
end
var socket = new Socket.server(args[0].to_i, 1)
print "[PORT] : {socket.port.to_s}"
var clients = new Array[Socket]
var max = socket
loop
var fs = new SocketObserver(true, true, true)
fs.readset.set(socket)
for c in clients do fs.readset.set(c)
if fs.select(max, 4, 0) == 0 then
print "Error occured in select {sys.errno.strerror}"
break
end
if fs.readset.is_set(socket) then
var ns = socket.accept
print "Accepting {ns.address} ... "
print "[Message from {ns.address}] : {ns.read(100)}"
ns.write("Goodbye client.")
print "Closing {ns.address} ..."
ns.close
end
end

View File

@@ -0,0 +1,94 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import template
### Here, definition of the specific templates
# The root template for composers
class TmplComposers
super Template
# Short list of composers
var composers = new Array[TmplComposer]
# Detailled list of composers
var composer_details = new Array[TmplComposerDetail]
# Add a composer in both lists
fun add_composer(firstname, lastname: String, birth, death: Int)
do
composers.add(new TmplComposer(lastname))
composer_details.add(new TmplComposerDetail(firstname, lastname, birth, death))
end
redef fun rendering do
add """
COMPOSERS
=========
"""
add_all composers
add """
DETAILS
=======
"""
add_all composer_details
end
end
# A composer in the short list of composers
class TmplComposer
super Template
# Short name
var name: String
init(name: String) do self.name = name
redef fun rendering do add "- {name}\n"
end
# A composer in the detailled list of composers
class TmplComposerDetail
super Template
var firstname: String
var lastname: String
var birth: Int
var death: Int
init(firstname, lastname: String, birth, death: Int) do
self.firstname = firstname
self.lastname = lastname
self.birth = birth
self.death = death
end
redef fun rendering do add """
COMPOSER: {{{firstname}}} {{{lastname}}}
BIRTH...: {{{birth}}}
DEATH...: {{{death}}}
"""
end
### Here a simple usage of the templates
var f = new TmplComposers
f.add_composer("Johann Sebastian", "Bach", 1685, 1750)
f.add_composer("George Frideric", "Handel", 1685, 1759)
f.add_composer("Wolfgang Amadeus", "Mozart", 1756, 1791)
f.write_to(stdout)

View File

@@ -0,0 +1,46 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2014 Lucas Bajolet <r4pass@hotmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Sample module for a minimal chat server using Websockets on port 8088
module websocket_server
import websocket
var sock = new WebSocket(8088, 1)
var msg: String
if sock.listener.eof then
print sys.errno.strerror
end
sock.accept
while not sock.listener.eof do
if not sock.connected then sock.accept
if sys.stdin.poll_in then
msg = gets
printn "Received message : {msg}"
if msg == "exit" then sock.close
if msg == "disconnect" then sock.disconnect_client
sock.write(msg)
end
if sock.can_read(10) then
msg = sock.read_line
if msg != "" then print msg
end
end

80
samples/Nix/nginx.nix Normal file
View File

@@ -0,0 +1,80 @@
{ stdenv, fetchurl, fetchgit, openssl, zlib, pcre, libxml2, libxslt, expat
, rtmp ? false
, fullWebDAV ? false
, syslog ? false
, moreheaders ? false, ...}:
let
version = "1.4.4";
mainSrc = fetchurl {
url = "http://nginx.org/download/nginx-${version}.tar.gz";
sha256 = "1f82845mpgmhvm151fhn2cnqjggw9w7cvsqbva9rb320wmc9m63w";
};
rtmp-ext = fetchgit {
url = git://github.com/arut/nginx-rtmp-module.git;
rev = "1cfb7aeb582789f3b15a03da5b662d1811e2a3f1";
sha256 = "03ikfd2l8mzsjwx896l07rdrw5jn7jjfdiyl572yb9jfrnk48fwi";
};
dav-ext = fetchgit {
url = git://github.com/arut/nginx-dav-ext-module.git;
rev = "54cebc1f21fc13391aae692c6cce672fa7986f9d";
sha256 = "1dvpq1fg5rslnl05z8jc39sgnvh3akam9qxfl033akpczq1bh8nq";
};
syslog-ext = fetchgit {
url = https://github.com/yaoweibin/nginx_syslog_patch.git;
rev = "165affd9741f0e30c4c8225da5e487d33832aca3";
sha256 = "14dkkafjnbapp6jnvrjg9ip46j00cr8pqc2g7374z9aj7hrvdvhs";
};
moreheaders-ext = fetchgit {
url = https://github.com/agentzh/headers-more-nginx-module.git;
rev = "refs/tags/v0.23";
sha256 = "12pbjgsxnvcf2ff2i2qdn39q4cm5czlgrng96j8ml4cgxvnbdh39";
};
in
stdenv.mkDerivation rec {
name = "nginx-${version}";
src = mainSrc;
buildInputs = [ openssl zlib pcre libxml2 libxslt
] ++ stdenv.lib.optional fullWebDAV expat;
patches = if syslog then [ "${syslog-ext}/syslog_1.4.0.patch" ] else [];
configureFlags = [
"--with-http_ssl_module"
"--with-http_spdy_module"
"--with-http_xslt_module"
"--with-http_sub_module"
"--with-http_dav_module"
"--with-http_gzip_static_module"
"--with-http_secure_link_module"
"--with-ipv6"
# Install destination problems
# "--with-http_perl_module"
] ++ stdenv.lib.optional rtmp "--add-module=${rtmp-ext}"
++ stdenv.lib.optional fullWebDAV "--add-module=${dav-ext}"
++ stdenv.lib.optional syslog "--add-module=${syslog-ext}"
++ stdenv.lib.optional moreheaders "--add-module=${moreheaders-ext}";
preConfigure = ''
export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I${libxml2 }/include/libxml2"
'';
# escape example
postInstall = ''
mv $out/sbin $out/bin ''' ''${
${ if true then ${ "" } else false }
'';
meta = {
description = "A reverse proxy and lightweight webserver";
maintainers = [ stdenv.lib.maintainers.raskin];
platforms = stdenv.lib.platforms.all;
inherit version;
};
}

38
samples/Pike/Error.pmod Normal file
View File

@@ -0,0 +1,38 @@
#pike __REAL_VERSION__
constant Generic = __builtin.GenericError;
constant Index = __builtin.IndexError;
constant BadArgument = __builtin.BadArgumentError;
constant Math = __builtin.MathError;
constant Resource = __builtin.ResourceError;
constant Permission = __builtin.PermissionError;
constant Decode = __builtin.DecodeError;
constant Cpp = __builtin.CppError;
constant Compilation = __builtin.CompilationError;
constant MasterLoad = __builtin.MasterLoadError;
constant ModuleLoad = __builtin.ModuleLoadError;
//! Returns an Error object for any argument it receives. If the
//! argument already is an Error object or is empty, it does nothing.
object mkerror(mixed error)
{
if (error == UNDEFINED)
return error;
if (objectp(error) && error->is_generic_error)
return error;
if (arrayp(error))
return Error.Generic(@error);
if (stringp(error))
return Error.Generic(error);
return Error.Generic(sprintf("%O", error));
}

360
samples/Pike/FakeFile.pike Normal file
View File

@@ -0,0 +1,360 @@
#pike __REAL_VERSION__
//! A string wrapper that pretends to be a @[Stdio.File] object
//! in addition to some features of a @[Stdio.FILE] object.
//! This constant can be used to distinguish a FakeFile object
//! from a real @[Stdio.File] object.
constant is_fake_file = 1;
protected string data;
protected int ptr;
protected int(0..1) r;
protected int(0..1) w;
protected int mtime;
protected function read_cb;
protected function read_oob_cb;
protected function write_cb;
protected function write_oob_cb;
protected function close_cb;
//! @seealso
//! @[Stdio.File()->close()]
int close(void|string direction) {
direction = lower_case(direction||"rw");
int cr = has_value(direction, "r");
int cw = has_value(direction, "w");
if(cr) {
r = 0;
}
if(cw) {
w = 0;
}
// FIXME: Close callback
return 1;
}
//! @decl void create(string data, void|string type, void|int pointer)
//! @seealso
//! @[Stdio.File()->create()]
void create(string _data, void|string type, int|void _ptr) {
if(!_data) error("No data string given to FakeFile.\n");
data = _data;
ptr = _ptr;
mtime = time();
if(type) {
type = lower_case(type);
if(has_value(type, "r"))
r = 1;
if(has_value(type, "w"))
w = 1;
}
else
r = w = 1;
}
protected string make_type_str() {
string type = "";
if(r) type += "r";
if(w) type += "w";
return type;
}
//! @seealso
//! @[Stdio.File()->dup()]
this_program dup() {
return this_program(data, make_type_str(), ptr);
}
//! Always returns 0.
//! @seealso
//! @[Stdio.File()->errno()]
int errno() { return 0; }
//! Returns size and the creation time of the string.
Stdio.Stat stat() {
Stdio.Stat st = Stdio.Stat();
st->size = sizeof(data);
st->mtime=st->ctime=mtime;
st->atime=time();
return st;
}
//! @seealso
//! @[Stdio.File()->line_iterator()]
String.SplitIterator line_iterator(int|void trim) {
if(trim)
return String.SplitIterator( data-"\r", '\n' );
return String.SplitIterator( data, '\n' );
}
protected mixed id;
//! @seealso
//! @[Stdio.File()->query_id()]
mixed query_id() { return id; }
//! @seealso
//! @[Stdio.File()->set_id()]
void set_id(mixed _id) { id = _id; }
//! @seealso
//! @[Stdio.File()->read_function()]
function(:string) read_function(int nbytes) {
return lambda() { return read(nbytes); };
}
//! @seealso
//! @[Stdio.File()->peek()]
int(-1..1) peek(int|float|void timeout) {
if(!r) return -1;
if(ptr >= sizeof(data)) return 0;
return 1;
}
//! Always returns 0.
//! @seealso
//! @[Stdio.File()->query_address()]
string query_address(void|int(0..1) is_local) { return 0; }
//! @seealso
//! @[Stdio.File()->read()]
string read(void|int(0..) len, void|int(0..1) not_all) {
if(!r) return 0;
if (len < 0) error("Cannot read negative number of characters.\n");
int start=ptr;
ptr += len;
if(zero_type(len) || ptr>sizeof(data))
ptr = sizeof(data);
// FIXME: read callback
return data[start..ptr-1];
}
//! @seealso
//! @[Stdio.FILE()->gets()]
string gets() {
if(!r) return 0;
string ret;
sscanf(data,"%*"+(string)ptr+"s%[^\n]",ret);
if(ret)
{
ptr+=sizeof(ret)+1;
if(ptr>sizeof(data))
{
ptr=sizeof(data);
if(!sizeof(ret))
ret = 0;
}
}
// FIXME: read callback
return ret;
}
//! @seealso
//! @[Stdio.FILE()->getchar()]
int getchar() {
if(!r) return 0;
int c;
if(catch(c=data[ptr]))
c=-1;
else
ptr++;
// FIXME: read callback
return c;
}
//! @seealso
//! @[Stdio.FILE()->unread()]
void unread(string s) {
if(!r) return;
if(data[ptr-sizeof(s)..ptr-1]==s)
ptr-=sizeof(s);
else
{
data=s+data[ptr..];
ptr=0;
}
}
//! @seealso
//! @[Stdio.File()->seek()]
int seek(int pos, void|int mult, void|int add) {
if(mult)
pos = pos*mult+add;
if(pos<0)
{
pos = sizeof(data)+pos;
if( pos < 0 )
pos = 0;
}
ptr = pos;
if( ptr > strlen( data ) )
ptr = strlen(data);
return ptr;
}
//! Always returns 1.
//! @seealso
//! @[Stdio.File()->sync()]
int(1..1) sync() { return 1; }
//! @seealso
//! @[Stdio.File()->tell()]
int tell() { return ptr; }
//! @seealso
//! @[Stdio.File()->truncate()]
int(0..1) truncate(int length) {
data = data[..length-1];
return sizeof(data)==length;
}
//! @seealso
//! @[Stdio.File()->write()]
int(-1..) write(string|array(string) str, mixed ... extra) {
if(!w) return -1;
if(arrayp(str)) str=str*"";
if(sizeof(extra)) str=sprintf(str, @extra);
if(ptr==sizeof(data)) {
data += str;
ptr = sizeof(data);
}
else if(sizeof(str)==1)
data[ptr++] = str[0];
else {
data = data[..ptr-1] + str + data[ptr+sizeof(str)..];
ptr += sizeof(str);
}
// FIXME: write callback
return sizeof(str);
}
//! @seealso
//! @[Stdio.File()->set_blocking]
void set_blocking() {
close_cb = 0;
read_cb = 0;
read_oob_cb = 0;
write_cb = 0;
write_oob_cb = 0;
}
//! @seealso
//! @[Stdio.File()->set_blocking_keep_callbacks]
void set_blocking_keep_callbacks() { }
//! @seealso
//! @[Stdio.File()->set_blocking]
void set_nonblocking(function rcb, function wcb, function ccb,
function rocb, function wocb) {
read_cb = rcb;
write_cb = wcb;
close_cb = ccb;
read_oob_cb = rocb;
write_oob_cb = wocb;
}
//! @seealso
//! @[Stdio.File()->set_blocking_keep_callbacks]
void set_nonblocking_keep_callbacks() { }
//! @seealso
//! @[Stdio.File()->set_close_callback]
void set_close_callback(function cb) { close_cb = cb; }
//! @seealso
//! @[Stdio.File()->set_read_callback]
void set_read_callback(function cb) { read_cb = cb; }
//! @seealso
//! @[Stdio.File()->set_read_oob_callback]
void set_read_oob_callback(function cb) { read_oob_cb = cb; }
//! @seealso
//! @[Stdio.File()->set_write_callback]
void set_write_callback(function cb) { write_cb = cb; }
//! @seealso
//! @[Stdio.File()->set_write_oob_callback]
void set_write_oob_callback(function cb) { write_oob_cb = cb; }
//! @seealso
//! @[Stdio.File()->query_close_callback]
function query_close_callback() { return close_cb; }
//! @seealso
//! @[Stdio.File()->query_read_callback]
function query_read_callback() { return read_cb; }
//! @seealso
//! @[Stdio.File()->query_read_oob_callback]
function query_read_oob_callback() { return read_oob_cb; }
//! @seealso
//! @[Stdio.File()->query_write_callback]
function query_write_callback() { return write_cb; }
//! @seealso
//! @[Stdio.File()->query_write_oob_callback]
function query_write_oob_callback() { return write_oob_cb; }
string _sprintf(int t) {
return t=='O' && sprintf("%O(%d,%O)", this_program, sizeof(data),
make_type_str());
}
// FakeFile specials.
//! A FakeFile can be casted to a string.
mixed cast(string to) {
switch(to) {
case "string": return data;
case "object": return this;
}
error("Can not cast object to %O.\n", to);
}
//! Sizeof on a FakeFile returns the size of its contents.
int(0..) _sizeof() {
return sizeof(data);
}
//! @ignore
#define NOPE(X) mixed X (mixed ... args) { error("This is a FakeFile. %s is not available.\n", #X); }
NOPE(assign);
NOPE(async_connect);
NOPE(connect);
NOPE(connect_unix);
NOPE(open);
NOPE(open_socket);
NOPE(pipe);
NOPE(tcgetattr);
NOPE(tcsetattr);
// Stdio.Fd
NOPE(dup2);
NOPE(lock); // We could implement this
NOPE(mode); // We could implement this
NOPE(proxy); // We could implement this
NOPE(query_fd);
NOPE(read_oob);
NOPE(set_close_on_exec);
NOPE(set_keepalive);
NOPE(trylock); // We could implement this
NOPE(write_oob);
//! @endignore

View File

@@ -0,0 +1,260 @@
:- module(format_spec, [ format_error/2
, format_spec/2
, format_spec//1
, spec_arity/2
, spec_types/2
]).
:- use_module(library(dcg/basics), [eos//0, integer//1, string_without//2]).
:- use_module(library(error)).
:- use_module(library(when), [when/2]).
% TODO loading this module is optional
% TODO it's for my own convenience during development
%:- use_module(library(mavis)).
%% format_error(+Goal, -Error:string) is nondet.
%
% True if Goal exhibits an Error in its format string. The
% Error string describes what is wrong with Goal. Iterates each
% error on backtracking.
%
% Goal may be one of the following predicates:
%
% * format/2
% * format/3
% * debug/3
format_error(format(Format,Args), Error) :-
format_error_(Format, Args,Error).
format_error(format(_,Format,Args), Error) :-
format_error_(Format,Args,Error).
format_error(debug(_,Format,Args), Error) :-
format_error_(Format,Args,Error).
format_error_(Format,Args,Error) :-
format_spec(Format, Spec),
!,
is_list(Args),
spec_types(Spec, Types),
types_error(Args, Types, Error).
format_error_(Format,_,Error) :-
% \+ format_spec(Format, _),
format(string(Error), "Invalid format string: ~q", [Format]).
types_error(Args, Types, Error) :-
length(Types, TypesLen),
length(Args, ArgsLen),
TypesLen =\= ArgsLen,
!,
format( string(Error)
, "Wrong argument count. Expected ~d, got ~d"
, [TypesLen, ArgsLen]
).
types_error(Args, Types, Error) :-
types_error_(Args, Types, Error).
types_error_([Arg|_],[Type|_],Error) :-
ground(Arg),
\+ is_of_type(Type,Arg),
message_to_string(error(type_error(Type,Arg),_Location),Error).
types_error_([_|Args],[_|Types],Error) :-
types_error_(Args, Types, Error).
% check/0 augmentation
:- multifile check:checker/2.
:- dynamic check:checker/2.
check:checker(format_spec:checker, "format/2 strings and arguments").
:- dynamic format_fail/3.
checker :-
prolog_walk_code([ module_class([user])
, infer_meta_predicates(false)
, autoload(false) % format/{2,3} are always loaded
, undefined(ignore)
, trace_reference(_)
, on_trace(check_format)
]),
retract(format_fail(Goal,Location,Error)),
print_message(warning, format_error(Goal,Location,Error)),
fail. % iterate all errors
checker. % succeed even if no errors are found
check_format(Module:Goal, _Caller, Location) :-
predicate_property(Module:Goal, imported_from(Source)),
memberchk(Source, [system,prolog_debug]),
can_check(Goal),
format_error(Goal, Error),
assert(format_fail(Goal, Location, Error)),
fail.
check_format(_,_,_). % succeed to avoid printing goals
% true if format_error/2 can check this goal
can_check(Goal) :-
once(clause(format_error(Goal,_),_)).
prolog:message(format_error(Goal,Location,Error)) -->
prolog:message_location(Location),
['~n In goal: ~q~n ~s'-[Goal,Error]].
%% format_spec(-Spec)//
%
% DCG for parsing format strings. It doesn't yet generate format
% strings from a spec. See format_spec/2 for details.
format_spec([]) -->
eos.
format_spec([escape(Numeric,Modifier,Action)|Rest]) -->
"~",
numeric_argument(Numeric),
modifier_argument(Modifier),
action(Action),
format_spec(Rest).
format_spec([text(String)|Rest]) -->
{ when((ground(String);ground(Codes)),string_codes(String, Codes)) },
string_without("~", Codes),
{ Codes \= [] },
format_spec(Rest).
%% format_spec(+Format, -Spec:list) is semidet.
%
% Parse a format string. Each element of Spec is one of the following:
%
% * `text(Text)` - text sent to the output as is
% * `escape(Num,Colon,Action)` - a format escape
%
% `Num` represents the optional numeric portion of an esape. `Colon`
% represents the optional colon in an escape. `Action` is an atom
% representing the action to be take by this escape.
format_spec(Format, Spec) :-
when((ground(Format);ground(Codes)),text_codes(Format, Codes)),
once(phrase(format_spec(Spec), Codes, [])).
%% spec_arity(+FormatSpec, -Arity:positive_integer) is det.
%
% True if FormatSpec requires format/2 to have Arity arguments.
spec_arity(Spec, Arity) :-
spec_types(Spec, Types),
length(Types, Arity).
%% spec_types(+FormatSpec, -Types:list(type)) is det.
%
% True if FormatSpec requires format/2 to have arguments of Types. Each
% value of Types is a type as described by error:has_type/2. This
% notion of types is compatible with library(mavis).
spec_types(Spec, Types) :-
phrase(spec_types(Spec), Types).
spec_types([]) -->
[].
spec_types([Item|Items]) -->
item_types(Item),
spec_types(Items).
item_types(text(_)) -->
[].
item_types(escape(Numeric,_,Action)) -->
numeric_types(Numeric),
action_types(Action).
numeric_types(number(_)) -->
[].
numeric_types(character(_)) -->
[].
numeric_types(star) -->
[number].
numeric_types(nothing) -->
[].
action_types(Action) -->
{ atom_codes(Action, [Code]) },
{ action_types(Code, Types) },
phrase(Types).
%% text_codes(Text:text, Codes:codes).
text_codes(Var, Codes) :-
var(Var),
!,
string_codes(Var, Codes).
text_codes(Atom, Codes) :-
atom(Atom),
!,
atom_codes(Atom, Codes).
text_codes(String, Codes) :-
string(String),
!,
string_codes(String, Codes).
text_codes(Codes, Codes) :-
is_of_type(codes, Codes).
numeric_argument(number(N)) -->
integer(N).
numeric_argument(character(C)) -->
"`",
[C].
numeric_argument(star) -->
"*".
numeric_argument(nothing) -->
"".
modifier_argument(colon) -->
":".
modifier_argument(no_colon) -->
\+ ":".
action(Action) -->
[C],
{ is_action(C) },
{ atom_codes(Action, [C]) }.
%% is_action(+Action:integer) is semidet.
%% is_action(-Action:integer) is multi.
%
% True if Action is a valid format/2 action character. Iterates all
% acceptable action characters, if Action is unbound.
is_action(Action) :-
action_types(Action, _).
%% action_types(?Action:integer, ?Types:list(type))
%
% True if Action consumes arguments matching Types. An action (like
% `~`), which consumes no arguments, has `Types=[]`. For example,
%
% ?- action_types(0'~, Types).
% Types = [].
% ?- action_types(0'a, Types).
% Types = [atom].
action_types(0'~, []).
action_types(0'a, [atom]).
action_types(0'c, [integer]). % specifically, a code
action_types(0'd, [integer]).
action_types(0'D, [integer]).
action_types(0'e, [float]).
action_types(0'E, [float]).
action_types(0'f, [float]).
action_types(0'g, [float]).
action_types(0'G, [float]).
action_types(0'i, [any]).
action_types(0'I, [integer]).
action_types(0'k, [any]).
action_types(0'n, []).
action_types(0'N, []).
action_types(0'p, [any]).
action_types(0'q, [any]).
action_types(0'r, [integer]).
action_types(0'R, [integer]).
action_types(0's, [text]).
action_types(0'@, [callable]).
action_types(0't, []).
action_types(0'|, []).
action_types(0'+, []).
action_types(0'w, [any]).
action_types(0'W, [any, list]).

194
samples/Prolog/func.pl Normal file
View File

@@ -0,0 +1,194 @@
:- module(func, [ op(675, xfy, ($))
, op(650, xfy, (of))
, ($)/2
, (of)/2
]).
:- use_module(library(list_util), [xfy_list/3]).
:- use_module(library(function_expansion)).
:- use_module(library(arithmetic)).
:- use_module(library(error)).
% true if the module whose terms are being read has specifically
% imported library(func).
wants_func :-
prolog_load_context(module, Module),
Module \== func, % we don't want func sugar ourselves
predicate_property(Module:of(_,_),imported_from(func)).
%% compile_function(+Term, -In, -Out, -Goal) is semidet.
%
% True if Term represents a function from In to Out
% implemented by calling Goal. This multifile hook is
% called by $/2 and of/2 to convert a term into a goal.
% It's used at compile time for macro expansion.
% It's used at run time to handle functions which aren't
% known at compile time.
% When called as a hook, Term is guaranteed to be =nonvar=.
%
% For example, to treat library(assoc) terms as functions which
% map a key to a value, one might define:
%
% :- multifile compile_function/4.
% compile_function(Assoc, Key, Value, Goal) :-
% is_assoc(Assoc),
% Goal = get_assoc(Key, Assoc, Value).
%
% Then one could write:
%
% list_to_assoc([a-1, b-2, c-3], Assoc),
% Two = Assoc $ b,
:- multifile compile_function/4.
compile_function(Var, _, _, _) :-
% variables storing functions must be evaluated at run time
% and can't be compiled, a priori, into a goal
var(Var),
!,
fail.
compile_function(Expr, In, Out, Out is Expr) :-
% arithmetic expression of one variable are simply evaluated
\+ string(Expr), % evaluable/1 throws exception with strings
arithmetic:evaluable(Expr),
term_variables(Expr, [In]).
compile_function(F, In, Out, func:Goal) :-
% composed functions
function_composition_term(F),
user:function_expansion(F, func:Functor, true),
Goal =.. [Functor,In,Out].
compile_function(F, In, Out, Goal) :-
% string interpolation via format templates
format_template(F),
( atom(F) ->
Goal = format(atom(Out), F, In)
; string(F) ->
Goal = format(string(Out), F, In)
; error:has_type(codes, F) ->
Goal = format(codes(Out), F, In)
; fail % to be explicit
).
compile_function(Dict, In, Out, Goal) :-
is_dict(Dict),
Goal = get_dict(In, Dict, Out).
%% $(+Function, +Argument) is det.
%
% Apply Function to an Argument. A Function is any predicate
% whose final argument generates output and whose penultimate argument
% accepts input.
%
% This is realized by expanding function application to chained
% predicate calls at compile time. Function application itself can
% be chained.
%
% ==
% Reversed = reverse $ sort $ [c,d,b].
% ==
:- meta_predicate $(2,+).
$(_,_) :-
throw(error(permission_error(call, predicate, ($)/2),
context(_, '$/2 must be subject to goal expansion'))).
user:function_expansion($(F,X), Y, Goal) :-
wants_func,
( func:compile_function(F, X, Y, Goal) ->
true
; var(F) -> Goal = % defer until run time
( func:compile_function(F, X, Y, P) ->
call(P)
; call(F, X, Y)
)
; Goal = call(F, X, Y)
).
%% of(+F, +G) is det.
%
% Creates a new function by composing F and G. The functions are
% composed at compile time to create a new, compiled predicate which
% behaves like a function. Function composition can be chained.
% Composed functions can also be applied with $/2.
%
% ==
% Reversed = reverse of sort $ [c,d,b].
% ==
:- meta_predicate of(2,2).
of(_,_).
%% format_template(Format) is semidet.
%
% True if Format is a template string suitable for format/3.
% The current check is very naive and should be improved.
format_template(Format) :-
atom(Format), !,
atom_codes(Format, Codes),
format_template(Codes).
format_template(Format) :-
string(Format),
!,
string_codes(Format, Codes),
format_template(Codes).
format_template(Format) :-
error:has_type(codes, Format),
memberchk(0'~, Format). % ' fix syntax highlighting
% True if the argument is a function composition term
function_composition_term(of(_,_)).
% Converts a function composition term into a list of functions to compose
functions_to_compose(Term, Funcs) :-
functor(Term, Op, 2),
Op = (of),
xfy_list(Op, Term, Funcs).
% Thread a state variable through a list of functions. This is similar
% to a DCG expansion, but much simpler.
thread_state([], [], Out, Out).
thread_state([F|Funcs], [Goal|Goals], In, Out) :-
( compile_function(F, In, Tmp, Goal) ->
true
; var(F) ->
instantiation_error(F)
; F =.. [Functor|Args],
append(Args, [In, Tmp], NewArgs),
Goal =.. [Functor|NewArgs]
),
thread_state(Funcs, Goals, Tmp, Out).
user:function_expansion(Term, func:Functor, true) :-
wants_func,
functions_to_compose(Term, Funcs),
debug(func, 'building composed function for: ~w', [Term]),
variant_sha1(Funcs, Sha),
format(atom(Functor), 'composed_function_~w', [Sha]),
debug(func, ' name: ~s', [Functor]),
( func:current_predicate(Functor/2) ->
debug(func, ' composed predicate already exists', [])
; true ->
reverse(Funcs, RevFuncs),
thread_state(RevFuncs, Threaded, In, Out),
xfy_list(',', Body, Threaded),
Head =.. [Functor, In, Out],
func:assert(Head :- Body),
func:compile_predicates([Functor/2])
).
% support foo(x,~,y) evaluation
user:function_expansion(Term, Output, Goal) :-
wants_func,
compound(Term),
% has a single ~ argument
setof( X
, ( arg(X,Term,Arg), Arg == '~' )
, [N]
),
% replace ~ with a variable
Term =.. [Name|Args0],
nth1(N, Args0, ~, Rest),
nth1(N, Args, Output, Rest),
Goal =.. [Name|Args].

View File

@@ -0,0 +1,241 @@
#
# Cinema 4D Python Plugin Source file
# https://github.com/nr-plugins/nr-xpresso-alignment-tools
#
# coding: utf-8
#
# Copyright (C) 2012, Niklas Rosenstein
# Licensed under the GNU General Public License
#
# XPAT - XPresso Alignment Tools
# ==============================
#
# The XPAT plugin provides tools for aligning nodes in the Cinema 4D
# XPresso Editor, improving readability of complex XPresso set-ups
# immensively.
#
# Requirements:
# - MAXON Cinema 4D R13+
# - Python `c4dtools` library. Get it from
# http://github.com/NiklasRosenstein/c4dtools
#
# Author: Niklas Rosenstein <rosensteinniklas@gmail.com>
# Version: 1.1 (01/06/2012)
import os
import sys
import json
import c4d
import c4dtools
import itertools
from c4d.modules import graphview as gv
from c4dtools.misc import graphnode
res, importer = c4dtools.prepare(__file__, __res__)
settings = c4dtools.helpers.Attributor({
'options_filename': res.file('config.json'),
})
def align_nodes(nodes, mode, spacing):
r"""
Aligns the passed nodes horizontally and apply the minimum spacing
between them.
"""
modes = ['horizontal', 'vertical']
if not nodes:
return
if mode not in modes:
raise ValueError('invalid mode, choices are: ' + ', '.join(modes))
get_0 = lambda x: x.x
get_1 = lambda x: x.y
set_0 = lambda x, v: setattr(x, 'x', v)
set_1 = lambda x, v: setattr(x, 'y', v)
if mode == 'vertical':
get_0, get_1 = get_1, get_0
set_0, set_1 = set_1, set_0
nodes = [graphnode.GraphNode(n) for n in nodes]
nodes.sort(key=lambda n: get_0(n.position))
midpoint = graphnode.find_nodes_mid(nodes)
# Apply the spacing between the nodes relative to the coordinate-systems
# origin. We can offset them later because we now the nodes' midpoint
# already.
first_position = nodes[0].position
new_positions = []
prev_offset = 0
for node in nodes:
# Compute the relative position of the node.
position = node.position
set_0(position, get_0(position) - get_0(first_position))
# Obtain it's size and check if the node needs to be re-placed.
size = node.size
if get_0(position) < prev_offset:
set_0(position, prev_offset)
prev_offset += spacing + get_0(size)
else:
prev_offset = get_0(position) + get_0(size) + spacing
set_1(position, get_1(midpoint))
new_positions.append(position)
# Center the nodes again.
bbox_size = prev_offset - spacing
bbox_size_2 = bbox_size * 0.5
for node, position in itertools.izip(nodes, new_positions):
# TODO: Here is some issue with offsetting the nodes. Some value
# dependent on the spacing must be added here to not make the nodes
# move horizontally/vertically although they have already been
# aligned.
set_0(position, get_0(midpoint) + get_0(position) - bbox_size_2 + spacing)
node.position = position
def align_nodes_shortcut(mode, spacing):
master = gv.GetMaster(0)
if not master:
return
root = master.GetRoot()
if not root:
return
nodes = graphnode.find_selected_nodes(root)
if nodes:
master.AddUndo()
align_nodes(nodes, mode, spacing)
c4d.EventAdd()
return True
class XPAT_Options(c4dtools.helpers.Attributor):
r"""
This class organizes the options for the XPAT plugin, i.e.
validating, loading and saving.
"""
defaults = {
'hspace': 50,
'vspace': 20,
}
def __init__(self, filename=None):
super(XPAT_Options, self).__init__()
self.load(filename)
def load(self, filename=None):
r"""
Load the options from file pointed to by filename. If filename
is None, it defaults to the filename defined in options in the
global scope.
"""
if filename is None:
filename = settings.options_filename
if os.path.isfile(filename):
self.dict_ = self.defaults.copy()
with open(filename, 'rb') as fp:
self.dict_.update(json.load(fp))
else:
self.dict_ = self.defaults.copy()
self.save()
def save(self, filename=None):
r"""
Save the options defined in XPAT_Options instance to HD.
"""
if filename is None:
filename = settings.options_filename
values = dict((k, v) for k, v in self.dict_.iteritems()
if k in self.defaults)
with open(filename, 'wb') as fp:
json.dump(values, fp)
class XPAT_OptionsDialog(c4d.gui.GeDialog):
r"""
This class implements the behavior of the XPAT options dialog,
taking care of storing the options on the HD and loading them
again on startup.
"""
# c4d.gui.GeDialog
def CreateLayout(self):
return self.LoadDialogResource(res.DLG_OPTIONS)
def InitValues(self):
self.SetLong(res.EDT_HSPACE, options.hspace)
self.SetLong(res.EDT_VSPACE, options.vspace)
return True
def Command(self, id, msg):
if id == res.BTN_SAVE:
options.hspace = self.GetLong(res.EDT_HSPACE)
options.vspace = self.GetLong(res.EDT_VSPACE)
options.save()
self.Close()
return True
class XPAT_Command_OpenOptionsDialog(c4dtools.plugins.Command):
r"""
This Cinema 4D CommandData plugin opens the XPAT options dialog
when being executed.
"""
def __init__(self):
super(XPAT_Command_OpenOptionsDialog, self).__init__()
self._dialog = None
@property
def dialog(self):
if not self._dialog:
self._dialog = XPAT_OptionsDialog()
return self._dialog
# c4dtools.plugins.Command
PLUGIN_ID = 1029621
PLUGIN_NAME = res.string.XPAT_COMMAND_OPENOPTIONSDIALOG()
PLUGIN_HELP = res.string.XPAT_COMMAND_OPENOPTIONSDIALOG_HELP()
# c4d.gui.CommandData
def Execute(self, doc):
return self.dialog.Open(c4d.DLG_TYPE_MODAL)
class XPAT_Command_AlignHorizontal(c4dtools.plugins.Command):
PLUGIN_ID = 1029538
PLUGIN_NAME = res.string.XPAT_COMMAND_ALIGNHORIZONTAL()
PLUGIN_ICON = res.file('xpresso-align-h.png')
PLUGIN_HELP = res.string.XPAT_COMMAND_ALIGNHORIZONTAL_HELP()
def Execute(self, doc):
align_nodes_shortcut('horizontal', options.hspace)
return True
class XPAT_Command_AlignVertical(c4dtools.plugins.Command):
PLUGIN_ID = 1029539
PLUGIN_NAME = res.string.XPAT_COMMAND_ALIGNVERTICAL()
PLUGIN_ICON = res.file('xpresso-align-v.png')
PLUGIN_HELP = res.string.XPAT_COMMAND_ALIGNVERTICAL_HELP()
def Execute(self, doc):
align_nodes_shortcut('vertical', options.vspace)
return True
options = XPAT_Options()
if __name__ == '__main__':
c4dtools.plugins.main()

30
samples/QMake/complex.pro Normal file
View File

@@ -0,0 +1,30 @@
# This QMake file is complex, as it usese
# boolean operators and function calls
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
# We could use some OpenGL right now
contains(QT_CONFIG, opengl) | contains(QT_CONFIG, opengles2) {
QT += opengl
} else {
DEFINES += QT_NO_OPENGL
}
TEMPLATE = app
win32 {
TARGET = BlahApp
RC_FILE = Resources/winres.rc
}
!win32 { TARGET = blahapp }
# Let's add a PRI file!
include(functions.pri)
SOURCES += file.cpp
HEADERS += file.h
FORMS += file.ui
RESOURCES += res.qrc

View File

@@ -0,0 +1,8 @@
# QMake include file that calls some functions
# and does nothing else...
exists(.git/HEAD) {
system(git rev-parse HEAD >rev.txt)
} else {
system(echo ThisIsNotAGitRepo >rev.txt)
}

View File

@@ -0,0 +1,2 @@
#!/usr/bin/qmake
message(This is QMake.)

17
samples/QMake/simple.pro Normal file
View File

@@ -0,0 +1,17 @@
# Simple QMake file
CONFIG += qt
QT += core gui
TEMPLATE = app
TARGET = simpleapp
SOURCES += file.cpp \
file2.c \
This/Is/Folder/file3.cpp
HEADERS += file.h \
file2.h \
This/Is/Folder/file3.h
FORMS += This/Is/Folder/file3.ui \
Test.ui

View File

@@ -0,0 +1,19 @@
Pry.config.commands.import Pry::ExtendedCommands::Experimental
Pry.config.pager = false
Pry.config.color = false
Pry.config.commands.alias_command "lM", "ls -M"
Pry.config.commands.command "add", "Add a list of numbers together" do |*args|
output.puts "Result is: #{args.map(&:to_i).inject(&:+)}"
end
Pry.config.history.should_save = false
Pry.config.prompt = [proc { "input> " },
proc { " | " }]
# Disable pry-buggy-plug:
Pry.plugins["buggy-plug"].disable!

28
samples/Zephir/filenames/exception.zep.c generated Normal file
View File

@@ -0,0 +1,28 @@
#ifdef HAVE_CONFIG_H
#include "../../ext_config.h"
#endif
#include <php.h>
#include "../../php_ext.h"
#include "../../ext.h"
#include <Zend/zend_operators.h>
#include <Zend/zend_exceptions.h>
#include <Zend/zend_interfaces.h>
#include "kernel/main.h"
/**
* Test\Router\Exception
*
* Exceptions generated by the router
*/
ZEPHIR_INIT_CLASS(Test_Router_Exception) {
ZEPHIR_REGISTER_CLASS_EX(Test\\Router, Exception, test, router_exception, zend_exception_get_default(TSRMLS_C), NULL, 0);
return SUCCESS;
}

View File

@@ -0,0 +1,4 @@
extern zend_class_entry *test_router_exception_ce;
ZEPHIR_INIT_CLASS(Test_Router_Exception);

View File

@@ -0,0 +1,8 @@
<?php
namespace Test\Router;
class Exception extends \Exception
{
}

View File

@@ -140,6 +140,13 @@ class TestBlob < Test::Unit::TestCase
assert !blob("Perl/script.pl").binary?
end
def test_all_binary
Samples.each do |sample|
blob = blob(sample[:path])
assert ! (blob.likely_binary? || blob.binary?), "#{sample[:path]} is a binary file"
end
end
def test_text
assert blob("Text/README").text?
assert blob("Text/dump.sql").text?
@@ -247,6 +254,13 @@ class TestBlob < Test::Unit::TestCase
# Generated VCR
assert blob("YAML/vcr_cassette.yml").generated?
# Generated by Zephir
assert blob("Zephir/filenames/exception.zep.c").generated?
assert blob("Zephir/filenames/exception.zep.h").generated?
assert blob("Zephir/filenames/exception.zep.php").generated?
assert !blob("Zephir/Router.zep").generated?
assert Linguist::Generated.generated?("node_modules/grunt/lib/grunt.js", nil)
end
@@ -271,6 +285,10 @@ class TestBlob < Test::Unit::TestCase
# 'thirdparty' directory
assert blob("thirdparty/lib/main.c").vendored?
# 'extern(al)' directory
assert blob("extern/util/__init__.py").vendored?
assert blob("external/jquery.min.js").vendored?
# C deps
assert blob("deps/http_parser/http_parser.c").vendored?
assert blob("deps/v8/src/v8.h").vendored?
@@ -375,6 +393,12 @@ class TestBlob < Test::Unit::TestCase
# NuGet Packages
assert blob("packages/Modernizr.2.0.6/Content/Scripts/modernizr-2.0.6-development-only.js").vendored?
# Normalize
assert blob("some/asset/path/normalize.css").vendored?
# Cocoapods
assert blob('Pods/blah').vendored?
# Html5shiv
assert blob("Scripts/html5shiv.js").vendored?
assert blob("Scripts/html5shiv.min.js").vendored?

View File

@@ -1,6 +1,7 @@
require 'linguist/heuristics'
require 'linguist/language'
require 'linguist/samples'
require 'linguist/file_blob'
require 'test/unit'
@@ -35,7 +36,8 @@ class TestHeuristcs < Test::Unit::TestCase
end
def test_detect_still_works_if_nothing_matches
match = Language.detect("Hello.m", fixture("Objective-C/hello.m"))
blob = Linguist::FileBlob.new(File.join(samples_path, "Objective-C/hello.m"))
match = Language.detect(blob)
assert_equal Language["Objective-C"], match
end

View File

@@ -3,22 +3,24 @@ require 'linguist/repository'
require 'test/unit'
class TestRepository < Test::Unit::TestCase
include Linguist
def repo(base_path)
Repository.from_directory(base_path)
def rugged_repository
@rugged ||= Rugged::Repository.new(File.expand_path("../../.git", __FILE__))
end
def linguist_repo
repo(File.expand_path("../..", __FILE__))
def master_oid
'd40b4a33deba710e2f494db357c654fbe5d4b419'
end
def linguist_repo(oid = master_oid)
Linguist::Repository.new(rugged_repository, oid)
end
def test_linguist_language
# assert_equal Language['Ruby'], linguist_repo.language
assert_equal 'Ruby', linguist_repo.language
end
def test_linguist_languages
# assert linguist_repo.languages[Language['Ruby']] > 10_000
assert linguist_repo.languages['Ruby'] > 10_000
end
def test_linguist_size
@@ -31,7 +33,18 @@ class TestRepository < Test::Unit::TestCase
assert linguist_repo.breakdown_by_file["Ruby"].include?("lib/linguist/language.rb")
end
def test_binary_override
assert_equal repo(File.expand_path("../../samples/Nimrod", __FILE__)).language, Language["Nimrod"]
def test_incremental_stats
old_commit = '3d7364877d6794f6cc2a86b493e893968a597332'
old_repo = linguist_repo(old_commit)
assert old_repo.languages['Ruby'] > 10_000
assert old_repo.size > 30_000
new_repo = Linguist::Repository.incremental(rugged_repository, master_oid, old_commit, old_repo.cache)
assert new_repo.languages['Ruby'] > old_repo.languages['Ruby']
assert new_repo.size > old_repo.size
assert_equal linguist_repo.cache, new_repo.cache
end
end