├── test ├── fixtures │ ├── subdir │ │ ├── a │ │ │ └── b │ │ │ │ └── c │ │ └── subdir.rb │ ├── exit │ │ └── exit.rb │ ├── autoload │ │ ├── foo.rb │ │ └── autoload.rb │ ├── resource │ │ ├── resource.txt │ │ ├── res │ │ │ └── resource.txt │ │ └── resource.rb │ ├── srcroot │ │ ├── share │ │ │ └── data.txt │ │ ├── lib │ │ │ └── srcrootlib.rb │ │ └── bin │ │ │ └── srcroot.rb │ ├── stdinredir │ │ ├── input.txt │ │ └── stdinredir.rb │ ├── exception │ │ └── exception.rb │ ├── hierarchy │ │ ├── assets │ │ │ ├── resource1.txt │ │ │ └── subdir │ │ │ │ └── resource2.txt │ │ └── hierarchy.rb │ ├── chdir │ │ └── chdir.rb │ ├── relloadpath │ │ ├── bin │ │ │ ├── sub │ │ │ │ └── sublib.rb │ │ │ ├── external.rb │ │ │ ├── chdir2.rb │ │ │ ├── chdir1.rb │ │ │ ├── dirname.rb │ │ │ ├── loadpath0.rb │ │ │ ├── loadpath1.rb │ │ │ ├── loadpath2.rb │ │ │ └── loadpath3.rb │ │ └── lib │ │ │ └── somelib.rb │ ├── exitstatus │ │ └── exitstatus.rb │ ├── helloworld │ │ └── helloworld.rb │ ├── relativerequire │ │ ├── somedir │ │ │ ├── otherfile.rb │ │ │ └── somefile.rb │ │ └── relativerequire.rb │ ├── bundlerusage │ │ ├── Gemfile │ │ └── bundlerusage.rb │ ├── autoloadnested │ │ ├── foo.rb │ │ └── autoloadnested.rb │ ├── stdoutredir │ │ └── stdoutredir.rb │ ├── buildarg │ │ └── buildarg.rb │ ├── gdbmdll │ │ └── gdbmdll.rb │ ├── writefile │ │ └── writefile.rb │ ├── autoloadmissing │ │ └── autoloadmissing.rb │ ├── rubycoreincl │ │ └── rubycoreincl.rb │ ├── environment │ │ └── environment.rb │ ├── check_includes │ │ └── check_includes.rb │ └── arguments │ │ └── arguments.rb └── test_ocra.rb ├── src ├── stub.rc ├── seb.exe ├── vit-ruby.ico ├── Makefile ├── edicon.c ├── lzma │ ├── Types.h │ ├── LzmaDec.h │ └── LzmaDec.c └── stub.c ├── lib └── ocra.rb ├── samples ├── pg_sample.rb ├── tkextlib.rb ├── readchar.rb ├── mime-types_sample.rb ├── win32ole.rb ├── bundler_git │ ├── Gemfile │ └── bundler_git.rb ├── activerecord_sample.rb ├── mech.rb ├── win32_api_sample.rb ├── tk.rb ├── sysproctable.rb ├── prawn_sample.rb ├── wxruby_sample.rbw └── watir_sample.rb ├── .gitignore ├── share └── ocra │ └── lzma.exe ├── Manifest.txt ├── .github └── workflows │ └── ruby.yml ├── .autotest ├── Rakefile ├── History.txt ├── README.md └── bin └── ocra /test/fixtures/subdir/a/b/c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/stub.rc: -------------------------------------------------------------------------------- 1 | 101 ICON vit-ruby.ico 2 | -------------------------------------------------------------------------------- /test/fixtures/exit/exit.rb: -------------------------------------------------------------------------------- 1 | exit 2 | -------------------------------------------------------------------------------- /test/fixtures/autoload/foo.rb: -------------------------------------------------------------------------------- 1 | class Foo 2 | end 3 | -------------------------------------------------------------------------------- /test/fixtures/resource/resource.txt: -------------------------------------------------------------------------------- 1 | someresource 2 | -------------------------------------------------------------------------------- /test/fixtures/srcroot/share/data.txt: -------------------------------------------------------------------------------- 1 | I am a file! 2 | -------------------------------------------------------------------------------- /test/fixtures/stdinredir/input.txt: -------------------------------------------------------------------------------- 1 | Hello, World! 2 | -------------------------------------------------------------------------------- /test/fixtures/exception/exception.rb: -------------------------------------------------------------------------------- 1 | raise "error" 2 | -------------------------------------------------------------------------------- /test/fixtures/hierarchy/assets/resource1.txt: -------------------------------------------------------------------------------- 1 | resource1 2 | -------------------------------------------------------------------------------- /lib/ocra.rb: -------------------------------------------------------------------------------- 1 | class Ocra 2 | VERSION = '1.3.10' 3 | end 4 | -------------------------------------------------------------------------------- /samples/pg_sample.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'pg' 3 | -------------------------------------------------------------------------------- /samples/tkextlib.rb: -------------------------------------------------------------------------------- 1 | require 'tk' 2 | require 'tkextlib' 3 | -------------------------------------------------------------------------------- /test/fixtures/chdir/chdir.rb: -------------------------------------------------------------------------------- 1 | Dir.chdir ENV["SystemRoot"] 2 | -------------------------------------------------------------------------------- /test/fixtures/resource/res/resource.txt: -------------------------------------------------------------------------------- 1 | anotherresource 2 | -------------------------------------------------------------------------------- /samples/readchar.rb: -------------------------------------------------------------------------------- 1 | exit if defined?(Ocra) 2 | STDIN.readchar 3 | -------------------------------------------------------------------------------- /test/fixtures/hierarchy/assets/subdir/resource2.txt: -------------------------------------------------------------------------------- 1 | resource2 2 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/bin/sub/sublib.rb: -------------------------------------------------------------------------------- 1 | class SubLib 2 | end 3 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/lib/somelib.rb: -------------------------------------------------------------------------------- 1 | class SomeLib 2 | end 3 | -------------------------------------------------------------------------------- /test/fixtures/srcroot/lib/srcrootlib.rb: -------------------------------------------------------------------------------- 1 | class SrcRootLib 2 | end 3 | -------------------------------------------------------------------------------- /test/fixtures/exitstatus/exitstatus.rb: -------------------------------------------------------------------------------- 1 | exit 167 if __FILE__ == $0 2 | -------------------------------------------------------------------------------- /test/fixtures/helloworld/helloworld.rb: -------------------------------------------------------------------------------- 1 | hello_world = "Hello, World!" 2 | -------------------------------------------------------------------------------- /test/fixtures/relativerequire/somedir/otherfile.rb: -------------------------------------------------------------------------------- 1 | OtherConst = 43212 2 | -------------------------------------------------------------------------------- /test/fixtures/relativerequire/somedir/somefile.rb: -------------------------------------------------------------------------------- 1 | SomeConst = 12312 2 | -------------------------------------------------------------------------------- /samples/mime-types_sample.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'mime/types' 3 | -------------------------------------------------------------------------------- /samples/win32ole.rb: -------------------------------------------------------------------------------- 1 | require 'win32ole' 2 | WIN32OLE.new('Wscript.Shell') 3 | -------------------------------------------------------------------------------- /src/seb.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larsch/ocra-ci-test/master/src/seb.exe -------------------------------------------------------------------------------- /test/fixtures/bundlerusage/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | gem "rake" 3 | -------------------------------------------------------------------------------- /test/fixtures/autoloadnested/foo.rb: -------------------------------------------------------------------------------- 1 | module Bar 2 | class Foo 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/bin/external.rb: -------------------------------------------------------------------------------- 1 | require "somelib" 2 | require "sublib" 3 | -------------------------------------------------------------------------------- /test/fixtures/stdoutredir/stdoutredir.rb: -------------------------------------------------------------------------------- 1 | puts "Hello, World!" unless defined?(Ocra) 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.exe 3 | bin/ocrasa.rb 4 | pkg 5 | README.txt 6 | ocrasa-*.zip 7 | 8 | -------------------------------------------------------------------------------- /samples/bundler_git/Gemfile: -------------------------------------------------------------------------------- 1 | gem "coderay", git: "https://github.com/rubychan/coderay.git" 2 | -------------------------------------------------------------------------------- /src/vit-ruby.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larsch/ocra-ci-test/master/src/vit-ruby.ico -------------------------------------------------------------------------------- /test/fixtures/buildarg/buildarg.rb: -------------------------------------------------------------------------------- 1 | raise "hell" unless ARGV == ["--some-option"] 2 | 3 | -------------------------------------------------------------------------------- /share/ocra/lzma.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larsch/ocra-ci-test/master/share/ocra/lzma.exe -------------------------------------------------------------------------------- /test/fixtures/gdbmdll/gdbmdll.rb: -------------------------------------------------------------------------------- 1 | require 'gdbm' 2 | exit 104 if $0 == __FILE__ and defined?(GDBM) 3 | -------------------------------------------------------------------------------- /samples/bundler_git/bundler_git.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'coderay' 3 | CodeRay::VERSION 4 | -------------------------------------------------------------------------------- /test/fixtures/stdinredir/stdinredir.rb: -------------------------------------------------------------------------------- 1 | exit if defined?(Ocra) 2 | exit 104 if gets == "Hello, World!\n" 3 | -------------------------------------------------------------------------------- /test/fixtures/writefile/writefile.rb: -------------------------------------------------------------------------------- 1 | File.open("output.txt", "w") do |f| 2 | f.write "output" 3 | end 4 | -------------------------------------------------------------------------------- /test/fixtures/srcroot/bin/srcroot.rb: -------------------------------------------------------------------------------- 1 | File.read(File.join(File.dirname(__FILE__), "..", "share", "data.txt")) 2 | -------------------------------------------------------------------------------- /test/fixtures/autoloadmissing/autoloadmissing.rb: -------------------------------------------------------------------------------- 1 | $:.unshift File.dirname(__FILE__) 2 | autoload :Foo, 'foo' 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/autoload/autoload.rb: -------------------------------------------------------------------------------- 1 | $:.unshift File.dirname(__FILE__) 2 | autoload :Foo, 'foo' 3 | Foo if __FILE__ == $0 4 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/bin/chdir2.rb: -------------------------------------------------------------------------------- 1 | Dir.chdir(File.dirname(__FILE__)) 2 | require "./../lib/somelib" 3 | require "./sub/sublib" 4 | -------------------------------------------------------------------------------- /test/fixtures/subdir/subdir.rb: -------------------------------------------------------------------------------- 1 | Dir.chdir(File.dirname(__FILE__)) 2 | raise "Can't find the file a/b/c" unless File.exist?("a/b/c") 3 | -------------------------------------------------------------------------------- /samples/activerecord_sample.rb: -------------------------------------------------------------------------------- 1 | require 'active_record' 2 | raise unless defined?(ActiveRecord) 3 | puts ActiveRecord::VERSION::STRING 4 | 5 | -------------------------------------------------------------------------------- /samples/mech.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'mechanize' 3 | require 'ostruct' 4 | require 'faster_csv' 5 | 6 | puts "Hello, World!" 7 | -------------------------------------------------------------------------------- /test/fixtures/rubycoreincl/rubycoreincl.rb: -------------------------------------------------------------------------------- 1 | require 'cgi' 2 | File.open("output.txt", "w") do |f| 3 | f.write CGI::escapeHTML("3 < 5") 4 | end 5 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/bin/chdir1.rb: -------------------------------------------------------------------------------- 1 | Dir.chdir(File.dirname(__FILE__)) 2 | require "../lib/somelib" 3 | require "sub/sublib" if RUBY_VERSION < "1.9.2" 4 | -------------------------------------------------------------------------------- /test/fixtures/autoloadnested/autoloadnested.rb: -------------------------------------------------------------------------------- 1 | $:.unshift File.dirname(__FILE__) 2 | module Bar 3 | autoload :Foo, 'foo' 4 | end 5 | Bar::Foo if __FILE__ == $0 6 | -------------------------------------------------------------------------------- /test/fixtures/bundlerusage/bundlerusage.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler/setup' 3 | require 'rake' 4 | 5 | # Just make sure the constant exists 6 | Rake 7 | -------------------------------------------------------------------------------- /test/fixtures/environment/environment.rb: -------------------------------------------------------------------------------- 1 | if $0 == __FILE__ 2 | File.open("environment", "wb") do |f| 3 | f.write(Marshal.dump(ENV.to_hash)) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/bin/dirname.rb: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(__FILE__), "../lib/somelib") 2 | require File.join(File.dirname(__FILE__), "sub/sublib") 3 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/bin/loadpath0.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 2 | # require "../lib/somelib" <- not valid require path 3 | require "sub/sublib" 4 | -------------------------------------------------------------------------------- /samples/win32_api_sample.rb: -------------------------------------------------------------------------------- 1 | require 'win32/api' 2 | exit if defined?(Ocra) 3 | Win32::API.new('MessageBox', 'LPPI', 'I', 'user32').call(0, "Hello, World!", "Greeting", 0) 4 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/bin/loadpath1.rb: -------------------------------------------------------------------------------- 1 | Dir.chdir(File.dirname(__FILE__)) 2 | $LOAD_PATH.unshift("../lib") 3 | $LOAD_PATH.unshift("sub") 4 | require "somelib" 5 | require "sublib" 6 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/bin/loadpath2.rb: -------------------------------------------------------------------------------- 1 | Dir.chdir(File.dirname(__FILE__)) 2 | $LOAD_PATH.unshift("./../lib") 3 | $LOAD_PATH.unshift("./sub") 4 | require "somelib" 5 | require "sublib" 6 | -------------------------------------------------------------------------------- /samples/tk.rb: -------------------------------------------------------------------------------- 1 | require 'tk' 2 | root = TkRoot.new { title "Hello, World!" } 3 | TkLabel.new(root) do 4 | text 'Hello, World!' 5 | pack { padx 15 ; pady 15; side 'left' } 6 | end 7 | Tk.mainloop 8 | -------------------------------------------------------------------------------- /test/fixtures/check_includes/check_includes.rb: -------------------------------------------------------------------------------- 1 | require 'rbconfig' 2 | exit if defined?(Ocra) 3 | if Dir[File.join(RbConfig::CONFIG["exec_prefix"], "include", "**", "*.h")].size != ARGV[0].to_i 4 | raise "Failed" 5 | end 6 | -------------------------------------------------------------------------------- /test/fixtures/relativerequire/relativerequire.rb: -------------------------------------------------------------------------------- 1 | $:.unshift File.dirname(__FILE__) 2 | require 'somedir/somefile' 3 | require 'SomeDir/otherfile' 4 | exit 160 if __FILE__ == $0 and defined?(SomeConst) and defined?(OtherConst) 5 | -------------------------------------------------------------------------------- /test/fixtures/relloadpath/bin/loadpath3.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.expand_path("../lib", File.dirname(__FILE__))) 2 | $LOAD_PATH.unshift(File.expand_path("sub", File.dirname(__FILE__))) 3 | require "somelib" 4 | require "sublib" 5 | -------------------------------------------------------------------------------- /Manifest.txt: -------------------------------------------------------------------------------- 1 | History.txt 2 | Manifest.txt 3 | README.md 4 | Rakefile 5 | bin/ocra 6 | share/ocra/lzma.exe 7 | share/ocra/stub.exe 8 | share/ocra/stubw.exe 9 | share/ocra/edicon.exe 10 | test/test_ocra.rb 11 | lib/ocra.rb 12 | -------------------------------------------------------------------------------- /samples/sysproctable.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | gem 'sys-proctable' 3 | require 'sys/proctable' 4 | require 'time' 5 | include Sys 6 | 7 | # Everything 8 | ProcTable.ps{ |p| 9 | puts p.pid.to_s + " " + p.comm 10 | } 11 | -------------------------------------------------------------------------------- /samples/prawn_sample.rb: -------------------------------------------------------------------------------- 1 | require 'prawn' 2 | exit if defined?(Ocra) 3 | Prawn::Document.generate('prawn_sample.pdf') do 4 | text "Hello, World!" 5 | font.instance_eval { find_font("Helvetica.afm") } or fail 6 | end 7 | File.unlink("prawn_sample.pdf") 8 | -------------------------------------------------------------------------------- /test/fixtures/hierarchy/hierarchy.rb: -------------------------------------------------------------------------------- 1 | Dir.chdir File.dirname(__FILE__) 2 | fail unless File.exist? "assets/resource1.txt" 3 | fail unless File.read("assets/resource1.txt") == "resource1\n" 4 | fail unless File.exist? "assets/subdir/resource2.txt" 5 | fail unless File.read("assets/subdir/resource2.txt") == "resource2\n" 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/resource/resource.rb: -------------------------------------------------------------------------------- 1 | exit 1 if File.read(File.join(File.dirname(__FILE__), "resource.txt")) != "someresource\n" 2 | exit 2 if File.read(File.join(File.dirname(__FILE__), "res", "resource.txt")) != "anotherresource\n" 3 | Dir.chdir(File.dirname(__FILE__)) 4 | exit 1 if File.read("resource.txt") != "someresource\n" 5 | exit 2 if File.read("res/resource.txt") != "anotherresource\n" 6 | -------------------------------------------------------------------------------- /test/fixtures/arguments/arguments.rb: -------------------------------------------------------------------------------- 1 | exit if defined?(Ocra) 2 | exit 1 if ARGV.size != 2 3 | exit 2 if ARGV[0] != "foo" 4 | if RUBY_VERSION == "1.8.6" 5 | # Ruby 1.8.6 has a command line quote-parsing bug that leaves extra 6 | # chars after the argument 7 | exit 3 if ARGV[1].index("bar baz \"quote\"") != 0 8 | else 9 | exit 3 if ARGV[1] != "bar baz \"quote\"" 10 | end 11 | exit 5 12 | -------------------------------------------------------------------------------- /.github/workflows/ruby.yml: -------------------------------------------------------------------------------- 1 | name: Ruby 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: windows-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Set up Ruby 2.6 17 | uses: actions/setup-ruby@v1 18 | with: 19 | ruby-version: 2.6.x 20 | - name: Build and test with Rake 21 | run: | 22 | gem install bundler hoe rake minitest 23 | bundle install --jobs 4 --retry 3 24 | bundle exec rake 25 | -------------------------------------------------------------------------------- /.autotest: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require 'autotest/restart' 4 | 5 | # Autotest.add_hook :initialize do |at| 6 | # at.extra_files << "../some/external/dependency.rb" 7 | # 8 | # at.libs << ":../some/external" 9 | # 10 | # at.add_exception 'vendor' 11 | # 12 | # at.add_mapping(/dependency.rb/) do |f, _| 13 | # at.files_matching(/test_.*rb$/) 14 | # end 15 | # 16 | # %w(TestA TestB).each do |klass| 17 | # at.extra_class_map[klass] = "test/test_misc.rb" 18 | # end 19 | # end 20 | 21 | # Autotest.add_hook :run_command do |at| 22 | # system "rake build" 23 | # end 24 | -------------------------------------------------------------------------------- /samples/wxruby_sample.rbw: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'wx' 3 | 4 | # Main window frame with a button. 5 | class MyMainWindow < Wx::Frame 6 | MY_BUTTON_ID = 1001 7 | def initialize 8 | super(nil, -1, "OCRA wxWidgets sample application") 9 | @button = Wx::Button.new(self, MY_BUTTON_ID, "OCRA Sample") 10 | evt_button(MY_BUTTON_ID) { close } 11 | end 12 | end 13 | 14 | # The sample application. 15 | class MyApp < Wx::App 16 | def on_init 17 | @frame = MyMainWindow.new 18 | @frame.show 19 | end 20 | end 21 | 22 | # Create MyApp 23 | app = MyApp.new 24 | 25 | # Run MyApp (unless Ocra is currently defined, and we are compiling 26 | # the application). 27 | app.main_loop unless defined?(Ocra) 28 | -------------------------------------------------------------------------------- /samples/watir_sample.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | require "watir" 3 | exit if defined?(Ocra) 4 | 5 | test_site = "http://www.google.com" 6 | 7 | ie = Watir::IE.new 8 | 9 | puts "Beginning of test: Google search." 10 | puts " Step 1: go to the test site: " + test_site 11 | ie.goto test_site 12 | 13 | puts " Step 2: enter 'pickaxe' in the search text field." 14 | ie.text_field(:name, "q").set "pickaxe" # "q" is the name of the search field 15 | 16 | puts " Step 3: click the 'Google Search' button." 17 | ie.button(:name, "btnG").click # "btnG" is the name of the Search button 18 | 19 | puts " Expected Result:" 20 | puts " A Google page with results should be shown. 'Programming Ruby' should be high on the list." 21 | 22 | puts " Actual Result:" 23 | if ie.text.include? "Programming Ruby" 24 | puts " Test Passed. Found the test string: 'Programming Ruby'. Actual Results match Expected Results." 25 | else 26 | puts " Test Failed! Could not find: 'Programming Ruby'." 27 | end 28 | 29 | ie.close 30 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | SRCS = lzma/LzmaDec.c 2 | OBJS = $(SRCS:.c=.o) stubicon.o 3 | CC = gcc 4 | BINDIR = $(CURDIR)/../share/ocra 5 | 6 | CFLAGS = -Wall -O2 -DWITH_LZMA -Ilzma -s 7 | STUB_CFLAGS = -D_CONSOLE $(CFLAGS) 8 | STUBW_CFLAGS = -mwindows $(CFLAGS) 9 | # -D_MBCS 10 | 11 | all: stub.exe stubw.exe edicon.exe 12 | 13 | stubicon.o: stub.rc 14 | windres -i $< -o $@ 15 | 16 | stub.exe: $(OBJS) stub.o 17 | $(CC) $(STUB_CFLAGS) $(OBJS) stub.o -o stub 18 | 19 | stubw.exe: $(OBJS) stubw.o 20 | $(CC) $(STUBW_CFLAGS) $(OBJS) stubw.o -o stubw 21 | 22 | edicon.exe: edicon.o 23 | $(CC) $(CFLAGS) edicon.o -o edicon 24 | 25 | stub.o: stub.c 26 | $(CC) $(STUB_CFLAGS) -o $@ -c $< 27 | 28 | stubw.o: stub.c 29 | $(CC) $(STUBW_CFLAGS) -o $@ -c $< 30 | 31 | clean: 32 | rm -f $(OBJS) stub.exe stubw.exe edicon.exe edicon.o stubw.o stub.o 33 | 34 | install: stub.exe stubw.exe edicon.exe 35 | cp -f stub.exe $(BINDIR)/stub.exe 36 | cp -f stubw.exe $(BINDIR)/stubw.exe 37 | cp -f edicon.exe $(BINDIR)/edicon.exe 38 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require "rubygems" 4 | require "hoe" 5 | 6 | Hoe.plugin :minitest 7 | 8 | spec = Hoe.spec "ocra" do 9 | developer "Lars Christensen", "larsch@belunktum.dk" 10 | license "MIT" 11 | end 12 | 13 | spec.urls.each { |key, url| url.chomp! } 14 | 15 | task :build_stub do 16 | sh "mingw32-make -C src" 17 | cp "src/stub.exe", "share/ocra/stub.exe" 18 | cp "src/stubw.exe", "share/ocra/stubw.exe" 19 | cp "src/edicon.exe", "share/ocra/edicon.exe" 20 | end 21 | 22 | file "share/ocra/stub.exe" => :build_stub 23 | file "share/ocra/stubw.exe" => :build_stub 24 | file "share/ocra/edicon.exe" => :build_stub 25 | 26 | task :test => :build_stub 27 | 28 | task :standalone => ["bin/ocrasa.rb"] 29 | 30 | standalone_zip = "bin/ocrasa-#{ENV["VERSION"]}.zip" 31 | 32 | file standalone_zip => "bin/ocrasa.rb" do 33 | chdir "bin" do 34 | sh "zip", "ocrasa-#{ENV["VERSION"]}.zip", "ocrasa.rb" 35 | end 36 | end 37 | 38 | task :release_standalone => standalone_zip do 39 | load "bin/ocra" 40 | sh "rubyforge add_release ocra ocra-standalone #{Ocra::VERSION} #{standalone_zip}" 41 | end 42 | 43 | file "bin/ocrasa.rb" => ["bin/ocra", "share/ocra/stub.exe", "share/ocra/stubw.exe", "share/ocra/lzma.exe", "share/ocra/edicon.exe"] do 44 | cp "bin/ocra", "bin/ocrasa.rb" 45 | File.open("bin/ocrasa.rb", "a") do |f| 46 | f.puts "__END__" 47 | 48 | stub = File.open("share/ocra/stub.exe", "rb") { |g| g.read } 49 | stub64 = [stub].pack("m") 50 | f.puts stub64.size 51 | f.puts stub64 52 | 53 | stub = File.open("share/ocra/stubw.exe", "rb") { |g| g.read } 54 | stub64 = [stub].pack("m") 55 | f.puts stub64.size 56 | f.puts stub64 57 | 58 | lzma = File.open("share/ocra/lzma.exe", "rb") { |g| g.read } 59 | lzma64 = [lzma].pack("m") 60 | f.puts lzma64.size 61 | f.puts lzma64 62 | 63 | lzma = File.open("share/ocra/edicon.exe", "rb") { |g| g.read } 64 | lzma64 = [lzma].pack("m") 65 | f.puts lzma64.size 66 | f.puts lzma64 67 | end 68 | end 69 | 70 | task :clean do 71 | rm_f Dir["{bin,samples}/*.exe"] 72 | rm_f Dir["share/ocra/{stub,stubw,edicon}.exe"] 73 | sh "mingw32-make -C src clean" 74 | end 75 | 76 | task :test_standalone => :standalone do 77 | ENV["TESTED_OCRA"] = "ocrasa.rb" 78 | system("rake test") 79 | ENV["TESTED_OCRA"] = nil 80 | end 81 | 82 | task :release_docs => :redocs do 83 | sh "pscp -r doc/* larsch@ocra.rubyforge.org:/var/www/gforge-projects/ocra" 84 | end 85 | 86 | # vim: syntax=Ruby 87 | -------------------------------------------------------------------------------- /src/edicon.c: -------------------------------------------------------------------------------- 1 | /** 2 | Changes the Icon in a PE executable. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #pragma pack(push, 2) 9 | 10 | /* Icon file header */ 11 | typedef struct 12 | { 13 | WORD Reserved; 14 | WORD ResourceType; 15 | WORD ImageCount; 16 | } IconFileHeader; 17 | 18 | /* Icon File directory entry structure */ 19 | typedef struct 20 | { 21 | BYTE Width; 22 | BYTE Height; 23 | BYTE Colors; 24 | BYTE Reserved; 25 | WORD Planes; 26 | WORD BitsPerPixel; 27 | DWORD ImageSize; 28 | DWORD ImageOffset; 29 | } IconDirectoryEntry; 30 | 31 | /* Group Icon Resource directory entry structure */ 32 | typedef struct 33 | { 34 | BYTE Width; 35 | BYTE Height; 36 | BYTE Colors; 37 | BYTE Reserved; 38 | WORD Planes; 39 | WORD BitsPerPixel; 40 | DWORD ImageSize; 41 | WORD ResourceID; 42 | } IconDirResEntry, *PIconDirResEntry; 43 | 44 | /* Group Icon Structore (RT_GROUP_ICON) */ 45 | typedef struct 46 | { 47 | WORD Reserved; 48 | WORD ResourceType; 49 | WORD ImageCount; 50 | IconDirResEntry Enries[0]; /* Number of these is in ImageCount */ 51 | } GroupIcon; 52 | 53 | #pragma pack(pop) 54 | 55 | BOOL UpdateIcon(LPTSTR ExecutableFileName, LPTSTR IconFileName) 56 | { 57 | HANDLE h = BeginUpdateResource(ExecutableFileName, FALSE); 58 | if (h == INVALID_HANDLE_VALUE) 59 | { 60 | printf("Failed to BeginUpdateResource\n"); 61 | return FALSE; 62 | } 63 | 64 | /* Read the Icon file */ 65 | HANDLE hIconFile = CreateFile(IconFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 66 | if (hIconFile == INVALID_HANDLE_VALUE) 67 | { 68 | fprintf(stderr, "Failed to open icon file.\n"); 69 | return FALSE; 70 | } 71 | DWORD Size = GetFileSize(hIconFile, NULL); 72 | BYTE* Data = LocalAlloc(LMEM_FIXED, Size); 73 | DWORD BytesRead; 74 | if (!ReadFile(hIconFile, Data, Size, &BytesRead, NULL)) 75 | { 76 | fprintf(stderr, "Failed to read icon file.\n"); 77 | return FALSE; 78 | } 79 | CloseHandle(hIconFile); 80 | 81 | IconFileHeader* header = (IconFileHeader*)Data; 82 | IconDirectoryEntry* entries = (IconDirectoryEntry*)(header + 1); 83 | 84 | /* Create the RT_ICON resources */ 85 | int i; 86 | for (i = 0; i < header->ImageCount; ++i) 87 | { 88 | BOOL b = UpdateResource(h, MAKEINTRESOURCE(RT_ICON), MAKEINTRESOURCE(101 + i), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), Data + entries[i].ImageOffset, entries[i].ImageSize); 89 | if (!b) 90 | { 91 | fprintf(stderr, "failed to UpdateResource %lu\n", GetLastError()); 92 | return FALSE; 93 | } 94 | } 95 | 96 | /* Create the RT_GROUP_ICON structure */ 97 | DWORD GroupIconSize = sizeof(GroupIcon) + header->ImageCount * sizeof(IconDirectoryEntry); 98 | GroupIcon* gi = (GroupIcon*)LocalAlloc(LMEM_FIXED, GroupIconSize); 99 | gi->Reserved = 0; 100 | gi->ResourceType = header->ResourceType; 101 | gi->ImageCount = header->ImageCount; 102 | for (i = 0; i < header->ImageCount; ++i) 103 | { 104 | IconDirResEntry* e = &gi->Enries[i]; 105 | e->Width = entries[i].Width; 106 | e->Height = entries[i].Height; 107 | e->Colors = entries[i].Colors; 108 | e->Reserved = entries[i].Reserved; 109 | e->Planes = entries[i].Planes; 110 | e->BitsPerPixel = entries[i].BitsPerPixel; 111 | e->ImageSize = entries[i].ImageSize; 112 | e->ResourceID = 101 + i; 113 | } 114 | 115 | /* Save the RT_GROUP_ICON resource */ 116 | BOOL b = UpdateResource(h, MAKEINTRESOURCE(RT_GROUP_ICON), MAKEINTRESOURCE(100), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), gi, GroupIconSize); 117 | if (!b) 118 | { 119 | fprintf(stderr, "Failed to create group icon.\n"); 120 | return FALSE; 121 | } 122 | 123 | if (!EndUpdateResource(h, FALSE)) 124 | { 125 | fprintf(stderr, "Failed to EndUpdateResource.\n"); 126 | return FALSE; 127 | } 128 | 129 | return TRUE; 130 | } 131 | 132 | int main(int argc, char* argv[]) 133 | { 134 | if (argc == 3) 135 | { 136 | if (UpdateIcon(argv[1], argv[2])) 137 | return 0; 138 | else 139 | return -1; 140 | } 141 | else 142 | { 143 | fprintf(stderr, "Usage: edicon.exe \n"); 144 | return -1; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/lzma/Types.h: -------------------------------------------------------------------------------- 1 | /* Types.h -- Basic types 2 | 2008-11-23 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __7Z_TYPES_H 5 | #define __7Z_TYPES_H 6 | 7 | #include 8 | 9 | #ifdef _WIN32 10 | #include 11 | #endif 12 | 13 | #define SZ_OK 0 14 | 15 | #define SZ_ERROR_DATA 1 16 | #define SZ_ERROR_MEM 2 17 | #define SZ_ERROR_CRC 3 18 | #define SZ_ERROR_UNSUPPORTED 4 19 | #define SZ_ERROR_PARAM 5 20 | #define SZ_ERROR_INPUT_EOF 6 21 | #define SZ_ERROR_OUTPUT_EOF 7 22 | #define SZ_ERROR_READ 8 23 | #define SZ_ERROR_WRITE 9 24 | #define SZ_ERROR_PROGRESS 10 25 | #define SZ_ERROR_FAIL 11 26 | #define SZ_ERROR_THREAD 12 27 | 28 | #define SZ_ERROR_ARCHIVE 16 29 | #define SZ_ERROR_NO_ARCHIVE 17 30 | 31 | typedef int SRes; 32 | 33 | #ifdef _WIN32 34 | typedef DWORD WRes; 35 | #else 36 | typedef int WRes; 37 | #endif 38 | 39 | #ifndef RINOK 40 | #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } 41 | #endif 42 | 43 | typedef unsigned char Byte; 44 | typedef short Int16; 45 | typedef unsigned short UInt16; 46 | 47 | #ifdef _LZMA_UINT32_IS_ULONG 48 | typedef long Int32; 49 | typedef unsigned long UInt32; 50 | #else 51 | typedef int Int32; 52 | typedef unsigned int UInt32; 53 | #endif 54 | 55 | #ifdef _SZ_NO_INT_64 56 | 57 | /* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. 58 | NOTES: Some code will work incorrectly in that case! */ 59 | 60 | typedef long Int64; 61 | typedef unsigned long UInt64; 62 | 63 | #else 64 | 65 | #if defined(_MSC_VER) || defined(__BORLANDC__) 66 | typedef __int64 Int64; 67 | typedef unsigned __int64 UInt64; 68 | #else 69 | typedef long long int Int64; 70 | typedef unsigned long long int UInt64; 71 | #endif 72 | 73 | #endif 74 | 75 | #ifdef _LZMA_NO_SYSTEM_SIZE_T 76 | typedef UInt32 SizeT; 77 | #else 78 | typedef size_t SizeT; 79 | #endif 80 | 81 | typedef int Bool; 82 | #define True 1 83 | #define False 0 84 | 85 | 86 | #ifdef _MSC_VER 87 | 88 | #if _MSC_VER >= 1300 89 | #define MY_NO_INLINE __declspec(noinline) 90 | #else 91 | #define MY_NO_INLINE 92 | #endif 93 | 94 | #define MY_CDECL __cdecl 95 | #define MY_STD_CALL __stdcall 96 | #define MY_FAST_CALL MY_NO_INLINE __fastcall 97 | 98 | #else 99 | 100 | #define MY_CDECL 101 | #define MY_STD_CALL 102 | #define MY_FAST_CALL 103 | 104 | #endif 105 | 106 | 107 | /* The following interfaces use first parameter as pointer to structure */ 108 | 109 | typedef struct 110 | { 111 | SRes (*Read)(void *p, void *buf, size_t *size); 112 | /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. 113 | (output(*size) < input(*size)) is allowed */ 114 | } ISeqInStream; 115 | 116 | /* it can return SZ_ERROR_INPUT_EOF */ 117 | SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); 118 | SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); 119 | SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); 120 | 121 | typedef struct 122 | { 123 | size_t (*Write)(void *p, const void *buf, size_t size); 124 | /* Returns: result - the number of actually written bytes. 125 | (result < size) means error */ 126 | } ISeqOutStream; 127 | 128 | typedef enum 129 | { 130 | SZ_SEEK_SET = 0, 131 | SZ_SEEK_CUR = 1, 132 | SZ_SEEK_END = 2 133 | } ESzSeek; 134 | 135 | typedef struct 136 | { 137 | SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ 138 | SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); 139 | } ISeekInStream; 140 | 141 | typedef struct 142 | { 143 | SRes (*Look)(void *p, void **buf, size_t *size); 144 | /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. 145 | (output(*size) > input(*size)) is not allowed 146 | (output(*size) < input(*size)) is allowed */ 147 | SRes (*Skip)(void *p, size_t offset); 148 | /* offset must be <= output(*size) of Look */ 149 | 150 | SRes (*Read)(void *p, void *buf, size_t *size); 151 | /* reads directly (without buffer). It's same as ISeqInStream::Read */ 152 | SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); 153 | } ILookInStream; 154 | 155 | SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); 156 | SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); 157 | 158 | /* reads via ILookInStream::Read */ 159 | SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); 160 | SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); 161 | 162 | #define LookToRead_BUF_SIZE (1 << 14) 163 | 164 | typedef struct 165 | { 166 | ILookInStream s; 167 | ISeekInStream *realStream; 168 | size_t pos; 169 | size_t size; 170 | Byte buf[LookToRead_BUF_SIZE]; 171 | } CLookToRead; 172 | 173 | void LookToRead_CreateVTable(CLookToRead *p, int lookahead); 174 | void LookToRead_Init(CLookToRead *p); 175 | 176 | typedef struct 177 | { 178 | ISeqInStream s; 179 | ILookInStream *realStream; 180 | } CSecToLook; 181 | 182 | void SecToLook_CreateVTable(CSecToLook *p); 183 | 184 | typedef struct 185 | { 186 | ISeqInStream s; 187 | ILookInStream *realStream; 188 | } CSecToRead; 189 | 190 | void SecToRead_CreateVTable(CSecToRead *p); 191 | 192 | typedef struct 193 | { 194 | SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); 195 | /* Returns: result. (result != SZ_OK) means break. 196 | Value (UInt64)(Int64)-1 for size means unknown value. */ 197 | } ICompressProgress; 198 | 199 | typedef struct 200 | { 201 | void *(*Alloc)(void *p, size_t size); 202 | void (*Free)(void *p, void *address); /* address can be 0 */ 203 | } ISzAlloc; 204 | 205 | #define IAlloc_Alloc(p, size) (p)->Alloc((p), size) 206 | #define IAlloc_Free(p, a) (p)->Free((p), a) 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /History.txt: -------------------------------------------------------------------------------- 1 | === 1.3.10 2 | 3 | * Reduce memory usage while building & compressing (avoids out of 4 | memory issue on really big programs). 5 | 6 | * Compile stub.exe with 32-bit compiler again 7 | 8 | === 1.3.9 9 | 10 | * Support Ruby 2.4.1p111 (include manifest) 11 | 12 | === 1.3.8 13 | 14 | * Use GetModuleFileNameW for DLL detection 15 | 16 | === 1.3.7 17 | 18 | * Workaround for handling of file names and directory name with 19 | non-ASCII characters (e.g. "invalid byte sequence in UTF-8") 20 | 21 | === 1.3.6 22 | 23 | * More robust cleanup of temporary files. Deletes using manual 24 | recursive method instead of using the shell. Will mark files for 25 | later deletion both using Windows (requires Administrator 26 | privileges) and a custom method that will remove old temporary files 27 | when the executable is restarted. 28 | 29 | === 1.3.5 30 | 31 | * Fixes for Ruby 2.2.2p95 32 | 33 | === 1.3.4 34 | 35 | * Workarounds for Ruby 2.1.5 36 | 37 | === 1.3.3 38 | 39 | * Rebuild executables with MinGW GCC 4.8.1-4. 40 | 41 | === 1.3.2 42 | 43 | * Refactored Gemfile handling for better compatibility with Ruby 44 | version. 45 | 46 | === 1.3.1 47 | 48 | * Now includes $LOADED_FEATURES even when script is not run to check 49 | dependencies. This fixes compatability with Ruby 1.9.3 where 50 | rubygems is always loaded. 51 | 52 | * Fixed compatability with Ruby 2.0.0: Temp-path alias in binary 53 | changed to be valid UTF-8 character. 54 | 55 | * README.txt updated related to --no-dep-run (karhatsu). 56 | 57 | * Fixes for Bundler handling (DavidMikeSimon). 58 | 59 | === 1.3.0 60 | 61 | * Fixed some additional corner cases with absolute and relative 62 | require & load paths. Extended test suite to cover a lot more 63 | cases. 64 | 65 | * Now provides a meaningful exit status code (1 on error, 0 on 66 | success). (DavidMikeSimon) 67 | 68 | * New option to _not_ run the script to detect dependencies 69 | (--no-dep-run). (DavidMikeSimon) 70 | 71 | * Bundler support using the --gemfile option. (DavidMikeSimon) 72 | 73 | * Debug mode support in the stub (--debug). Also --debug-extract to 74 | keep extracted files from executable. (DavidMikeSimon) 75 | 76 | * New gem behaviour yet again due to changes in Rubygems. See README 77 | file. 78 | 79 | === 1.2.0 80 | 81 | * Ignore console events (Ctrl-C, Ctrl-Break). Ruby process handles 82 | them anyway and exist, allowing the stub to clean up temporary 83 | files. 84 | 85 | * Temporary memory used for decompression is now freed before the ruby 86 | interpreter is launched by the stub. 87 | 88 | * Progress dialog is no longer displayed when removing temporary 89 | files. 90 | 91 | * Now includes most files from any require'd Rubygem (Now works with 92 | mime-types, oledb and other gems that load additional data files 93 | from the Gem installation). Some files are still ignored 94 | (e.g. Readme's). Use "--no-gem-filter" to make Ocra unconditionally 95 | include all files listed in the Gem specification (Thanks to Jorge 96 | L. Cangas for patch & ideas). 97 | 98 | * NameErrors are now rescued when attempting to load autoloadable 99 | constants. Hopefully resolves issues with ActiveRecord [#28488]. 100 | 101 | * Now works if the script changes environment or working directory 102 | while running. 103 | 104 | * Fixed a regression in 1.1.4 when resource files are specified; 105 | directory layout would not be maintained, e.g. when running "ocra 106 | bin/script share/data.dat". 107 | 108 | * Added support for passing arguments to script. Specify argument to 109 | your script after a "--" marker. Arguments will be passed both at 110 | compile time and run time. (#27815) 111 | 112 | * Now works if the source files are located beneath Ruby's 113 | exec_prefix. (#28505) 114 | 115 | === 1.1.4 116 | 117 | * The tempdir marker is now pretty-printed as "" in the 118 | output. 119 | 120 | * Fixed various issues with path and filenames being handled case 121 | sensitive. 122 | 123 | * Now uses config settings for Ruby executable names (should now also 124 | work with ruby installations built with --program-suffix). 125 | 126 | * Supported invoking ocra with an absolute path to the script. Will 127 | assume that the script is in the root of the source hierachy. 128 | 129 | === 1.1.3 130 | 131 | * Use Win32API (provided with Ruby) instead of win32-api (gem). 132 | 133 | * No longer sets GEM_HOME (which would override the default gem 134 | path). Instead sets GEM_PATH. Resolves issues with gems not loading 135 | on Ruby 1.9. 136 | 137 | === 1.1.2 138 | 139 | * Warnings can be disabled using --no-warnings. 140 | 141 | * Fixed not .exe being generated when script calls 'exit'. 142 | 143 | * Path to the generated executable is now avilable to the running 144 | script in the OCRA_EXECUTABLE environment variable. 145 | 146 | * Directories on the command line will now be created. 147 | 148 | * Supports path globs, fx. "ocra script.rb assets/**/*.png". (See 149 | documentation for Ruby's Dir class). 150 | 151 | * Fixed issue with spaces in temporary path (TMP environment). 152 | 153 | * Improved path comparison to ignore case (this is Windows after all) 154 | and be a bit more robust. 155 | 156 | * Added support for RubyGems installed in GEM_HOME (or other part 157 | handled by RubyGems). If not installed in the Ruby hierarchy, they 158 | will now be installed in a directory named 'gemhome' under the 159 | temporary directory. 160 | 161 | === 1.1.1 162 | 163 | * Fixed duplicate entries in the RUBYLIB environment variable. 164 | 165 | * Another slight fix for relative load paths. 166 | 167 | * RUBYOPT is now set to the value it had when OCRA was invoked. 168 | 169 | === 1.1.0 170 | 171 | * Added an icon to the executable. Can be replaced from a .ico file 172 | using the --icon option. 173 | 174 | * Improved handling of load paths added either from the command line 175 | (ruby -I), RUBYLIB environment variable or during the script (by 176 | modifying $: or $LOAD_PATH). 177 | 178 | * Now automatically detects loaded DLLs through Win32::API. Disable 179 | with --no-autodll. 180 | 181 | === 1.0.3 / 2009-05-25 182 | 183 | * Fixed invokation of executables with spaces in path names (#25966). 184 | 185 | * Fixed inverted handling of --windows & --console (#25974) 186 | 187 | * Fixed installation issue with RubyGems (missing "lib") 188 | 189 | === 1.0.2 / 2009-05-10 190 | 191 | * Added stubw.exe to gem (was missing 1.0.1) 192 | 193 | === 1.0.1 / 2009-05-05 194 | 195 | * Added stub with windows runtime for windowed applications 196 | (e.g. wxRuby) and fixed issue where OCRA would use ruby.exe instead 197 | of rubyw.exe for such programs. [#25774] 198 | 199 | === 1.0.0 / 2009-04-05 200 | 201 | * 1 major enhancement 202 | 203 | * Birthday! 204 | -------------------------------------------------------------------------------- /src/lzma/LzmaDec.h: -------------------------------------------------------------------------------- 1 | /* LzmaDec.h -- LZMA Decoder 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __LZMADEC_H 5 | #define __LZMADEC_H 6 | 7 | #include "Types.h" 8 | 9 | /* #define _LZMA_PROB32 */ 10 | /* _LZMA_PROB32 can increase the speed on some CPUs, 11 | but memory usage for CLzmaDec::probs will be doubled in that case */ 12 | 13 | #ifdef _LZMA_PROB32 14 | #define CLzmaProb UInt32 15 | #else 16 | #define CLzmaProb UInt16 17 | #endif 18 | 19 | 20 | /* ---------- LZMA Properties ---------- */ 21 | 22 | #define LZMA_PROPS_SIZE 5 23 | 24 | typedef struct _CLzmaProps 25 | { 26 | unsigned lc, lp, pb; 27 | UInt32 dicSize; 28 | } CLzmaProps; 29 | 30 | /* LzmaProps_Decode - decodes properties 31 | Returns: 32 | SZ_OK 33 | SZ_ERROR_UNSUPPORTED - Unsupported properties 34 | */ 35 | 36 | SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); 37 | 38 | 39 | /* ---------- LZMA Decoder state ---------- */ 40 | 41 | /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. 42 | Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ 43 | 44 | #define LZMA_REQUIRED_INPUT_MAX 20 45 | 46 | typedef struct 47 | { 48 | CLzmaProps prop; 49 | CLzmaProb *probs; 50 | Byte *dic; 51 | const Byte *buf; 52 | UInt32 range, code; 53 | SizeT dicPos; 54 | SizeT dicBufSize; 55 | UInt32 processedPos; 56 | UInt32 checkDicSize; 57 | unsigned state; 58 | UInt32 reps[4]; 59 | unsigned remainLen; 60 | int needFlush; 61 | int needInitState; 62 | UInt32 numProbs; 63 | unsigned tempBufSize; 64 | Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; 65 | } CLzmaDec; 66 | 67 | #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } 68 | 69 | void LzmaDec_Init(CLzmaDec *p); 70 | 71 | /* There are two types of LZMA streams: 72 | 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. 73 | 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ 74 | 75 | typedef enum 76 | { 77 | LZMA_FINISH_ANY, /* finish at any point */ 78 | LZMA_FINISH_END /* block must be finished at the end */ 79 | } ELzmaFinishMode; 80 | 81 | /* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! 82 | 83 | You must use LZMA_FINISH_END, when you know that current output buffer 84 | covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. 85 | 86 | If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, 87 | and output value of destLen will be less than output buffer size limit. 88 | You can check status result also. 89 | 90 | You can use multiple checks to test data integrity after full decompression: 91 | 1) Check Result and "status" variable. 92 | 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. 93 | 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. 94 | You must use correct finish mode in that case. */ 95 | 96 | typedef enum 97 | { 98 | LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ 99 | LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ 100 | LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ 101 | LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ 102 | LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ 103 | } ELzmaStatus; 104 | 105 | /* ELzmaStatus is used only as output value for function call */ 106 | 107 | 108 | /* ---------- Interfaces ---------- */ 109 | 110 | /* There are 3 levels of interfaces: 111 | 1) Dictionary Interface 112 | 2) Buffer Interface 113 | 3) One Call Interface 114 | You can select any of these interfaces, but don't mix functions from different 115 | groups for same object. */ 116 | 117 | 118 | /* There are two variants to allocate state for Dictionary Interface: 119 | 1) LzmaDec_Allocate / LzmaDec_Free 120 | 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs 121 | You can use variant 2, if you set dictionary buffer manually. 122 | For Buffer Interface you must always use variant 1. 123 | 124 | LzmaDec_Allocate* can return: 125 | SZ_OK 126 | SZ_ERROR_MEM - Memory allocation error 127 | SZ_ERROR_UNSUPPORTED - Unsupported properties 128 | */ 129 | 130 | SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); 131 | void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); 132 | 133 | SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); 134 | void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); 135 | 136 | /* ---------- Dictionary Interface ---------- */ 137 | 138 | /* You can use it, if you want to eliminate the overhead for data copying from 139 | dictionary to some other external buffer. 140 | You must work with CLzmaDec variables directly in this interface. 141 | 142 | STEPS: 143 | LzmaDec_Constr() 144 | LzmaDec_Allocate() 145 | for (each new stream) 146 | { 147 | LzmaDec_Init() 148 | while (it needs more decompression) 149 | { 150 | LzmaDec_DecodeToDic() 151 | use data from CLzmaDec::dic and update CLzmaDec::dicPos 152 | } 153 | } 154 | LzmaDec_Free() 155 | */ 156 | 157 | /* LzmaDec_DecodeToDic 158 | 159 | The decoding to internal dictionary buffer (CLzmaDec::dic). 160 | You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! 161 | 162 | finishMode: 163 | It has meaning only if the decoding reaches output limit (dicLimit). 164 | LZMA_FINISH_ANY - Decode just dicLimit bytes. 165 | LZMA_FINISH_END - Stream must be finished after dicLimit. 166 | 167 | Returns: 168 | SZ_OK 169 | status: 170 | LZMA_STATUS_FINISHED_WITH_MARK 171 | LZMA_STATUS_NOT_FINISHED 172 | LZMA_STATUS_NEEDS_MORE_INPUT 173 | LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK 174 | SZ_ERROR_DATA - Data error 175 | */ 176 | 177 | SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, 178 | const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); 179 | 180 | 181 | /* ---------- Buffer Interface ---------- */ 182 | 183 | /* It's zlib-like interface. 184 | See LzmaDec_DecodeToDic description for information about STEPS and return results, 185 | but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need 186 | to work with CLzmaDec variables manually. 187 | 188 | finishMode: 189 | It has meaning only if the decoding reaches output limit (*destLen). 190 | LZMA_FINISH_ANY - Decode just destLen bytes. 191 | LZMA_FINISH_END - Stream must be finished after (*destLen). 192 | */ 193 | 194 | SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, 195 | const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); 196 | 197 | 198 | /* ---------- One Call Interface ---------- */ 199 | 200 | /* LzmaDecode 201 | 202 | finishMode: 203 | It has meaning only if the decoding reaches output limit (*destLen). 204 | LZMA_FINISH_ANY - Decode just destLen bytes. 205 | LZMA_FINISH_END - Stream must be finished after (*destLen). 206 | 207 | Returns: 208 | SZ_OK 209 | status: 210 | LZMA_STATUS_FINISHED_WITH_MARK 211 | LZMA_STATUS_NOT_FINISHED 212 | LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK 213 | SZ_ERROR_DATA - Data error 214 | SZ_ERROR_MEM - Memory allocation error 215 | SZ_ERROR_UNSUPPORTED - Unsupported properties 216 | SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). 217 | */ 218 | 219 | SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 220 | const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, 221 | ELzmaStatus *status, ISzAlloc *alloc); 222 | 223 | #endif 224 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ocra 2 | 3 | home :: https://github.com/larsch/ocra/ 4 | 5 | issues :: http://github.com/larsch/ocra/issues 6 | 7 | forum :: http://groups.google.com/group/ruby-ocra 8 | 9 | ## Description 10 | 11 | OCRA (One-Click Ruby Application) builds Windows executables from Ruby 12 | source code. The executable is a self-extracting, self-running 13 | executable that contains the Ruby interpreter, your source code and 14 | any additionally needed ruby libraries or DLL. 15 | 16 | ## Features 17 | 18 | * LZMA Compression (optional, default on) 19 | * Both windowed/console mode supported 20 | * Includes gems based on usage, or from a Bundler Gemfile 21 | 22 | ## Problems & Bug Reporiting 23 | 24 | * Windows support only 25 | 26 | If you experience problems with OCRA or have found a bug, please use 27 | the issue tracker on GitHub (http://github.com/larsch/ocra/issues). 28 | You can also join the Google Group discussion forum to ask questions 29 | and get help (http://groups.google.com/group/ruby-ocra). 30 | 31 | ## Installation 32 | 33 | Gem: 34 | 35 | gem install ocra 36 | 37 | Alternatively you can download the gem at either 38 | http://rubygems.org/gems/ocra or 39 | https://github.com/larsch/ocra/releases/. 40 | 41 | Stand-alone Version: Get ocrasa.rb from 42 | https://github.com/larsch/ocra/releases/. Requires nothing but a 43 | working Ruby installation on Windows. 44 | 45 | ## Synopsis 46 | 47 | ### Building an executable: 48 | 49 | ocra script.rb 50 | 51 | Will package `script.rb`, the Ruby interpreter and all 52 | dependencies (gems and DLLs) into an executable named 53 | `script.exe`. 54 | 55 | ### Command line: 56 | 57 | ocra [options] script.rb [ ...] [--