diff --git a/AppKit/Resources/kuler_button.png b/AppKit/Resources/kuler_button.png
deleted file mode 100644
index bd766c45f..000000000
Binary files a/AppKit/Resources/kuler_button.png and /dev/null differ
diff --git a/AppKit/Resources/kuler_button_h.png b/AppKit/Resources/kuler_button_h.png
deleted file mode 100644
index 84b2866ed..000000000
Binary files a/AppKit/Resources/kuler_button_h.png and /dev/null differ
diff --git a/AppKit/rakefile b/AppKit/rakefile
new file mode 100644
index 000000000..13fe5b1c0
--- /dev/null
+++ b/AppKit/rakefile
@@ -0,0 +1,57 @@
+#!/usr/bin/env ruby
+
+require 'rake'
+require '../common'
+require 'objective-j'
+require 'objective-j/bundle'
+
+
+$PRODUCT = 'AppKit' + $CONFIGURATION
+$ENVIRONMENT_PRODUCT = File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'AppKit')
+
+task :build => [$PRODUCT, $ENVIRONMENT_PRODUCT]
+
+Specs = {}
+
+AppKitFiles = FileList['**/*.j'].exclude('CoreGraphics/CGContextCanvas.j', 'CoreGraphics/CGContextVML.j', 'Themes/**')
+
+# Debug Framework
+Specs[:AppKitDebug] = ObjectiveJ::BundleSpecification.new do |s|
+ s.name = 'AppKit'
+ s.identifier = 'com.280n.AppKit'
+ s.version = '0.6.5'
+ s.author = '280 North, Inc.'
+ s.email = 'feedback @nospam@ 280north.com'
+ s.summary = 'AppKit classes for Cappuccino'
+ s.sources = AppKitFiles
+ s.resources = FileList['Resources/*']
+ s.license = ObjectiveJ::License::LGPL_v2_1
+ s.build_path = File.join($BUILD_DIR, 'Debug', 'AppKit')
+ s.intermediates_path = File.join($BUILD_DIR, 'AppKit.build', 'Debug')
+ s.flags = ['PLATFORM_DOM', 'DEBUG']
+end
+
+bundle Specs[:AppKitDebug], :AppKitDebug
+
+# Release Framework
+Specs[:AppKitRelease] = ObjectiveJ::BundleSpecification.new do |s|
+ s.name = 'AppKit'
+ s.identifier = 'com.280n.AppKit'
+ s.version = '0.6.5'
+ s.author = '280 North, Inc.'
+ s.email = 'feedback @nospam@ 280north.com'
+ s.summary = 'AppKit classes for Cappuccino'
+ s.sources = AppKitFiles
+ s.resources = FileList['Resources/*']
+ s.license = ObjectiveJ::License::LGPL_v2_1
+ s.build_path = File.join($BUILD_DIR, 'Release', 'AppKit')
+ s.intermediates_path = File.join($BUILD_DIR, 'AppKit.build', 'Release')
+ s.flag = 'PLATFORM_DOM'
+end
+
+bundle Specs[:AppKitRelease], :AppKitRelease
+
+#Framework in environment directory
+file_d $ENVIRONMENT_PRODUCT => [$PRODUCT] do
+ cp_r(Specs[$PRODUCT.to_sym].build_path, $ENVIRONMENT_PRODUCT)
+end
diff --git a/Foundation/rakefile b/Foundation/rakefile
new file mode 100644
index 000000000..fca544604
--- /dev/null
+++ b/Foundation/rakefile
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+
+require 'rake'
+require '../common'
+require 'objective-j'
+require 'objective-j/bundle'
+
+
+$PRODUCT = 'Foundation' + $CONFIGURATION
+$ENVIRONMENT_PRODUCT = File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Foundation')
+
+task :build => [$PRODUCT, $ENVIRONMENT_PRODUCT]
+
+Specs = {}
+
+# Debug Framework
+Specs[:FoundationDebug] = ObjectiveJ::BundleSpecification.new do |s|
+ s.name = 'Foundation'
+ s.identifier = 'com.280n.Foundation'
+ s.version = '0.6.5'
+ s.author = '280 North, Inc.'
+ s.email = 'feedback @nospam@ 280north.com'
+ s.summary = 'Foundation classes for Cappuccino'
+ s.sources = FileList['*.j']
+ s.resources = FileList['Resources/*'].to_a
+ s.license = ObjectiveJ::License::LGPL_v2_1
+ s.build_path = File.join($BUILD_DIR, 'Debug', 'Foundation')
+ s.intermediates_path = File.join($BUILD_DIR, 'Foundation.build', 'Debug')
+ s.flag = 'DEBUG'
+end
+
+bundle Specs[:FoundationDebug], :FoundationDebug
+
+# Release Framework
+Specs[:FoundationRelease] = ObjectiveJ::BundleSpecification.new do |s|
+ s.name = 'Foundation'
+ s.identifier = 'com.280n.Foundation'
+ s.version = '0.6.5'
+ s.author = '280 North, Inc.'
+ s.email = 'feedback @nospam@ 280north.com'
+ s.summary = 'Foundation classes for Cappuccino'
+ s.sources = FileList['*.j']
+ s.resources = FileList['Resources/*'].to_a
+ s.license = ObjectiveJ::License::LGPL_v2_1
+ s.build_path = File.join($BUILD_DIR, 'Release', 'Foundation')
+ s.intermediates_path = File.join($BUILD_DIR, 'Foundation.build', 'Release')
+end
+
+bundle Specs[:FoundationRelease], :FoundationRelease
+
+#Framework in environment directory
+file_d $ENVIRONMENT_PRODUCT => [$PRODUCT] do
+ cp_r(Specs[$PRODUCT.to_sym].build_path, $ENVIRONMENT_PRODUCT)
+end
diff --git a/Objective-J/Object.j b/Objective-J/Runtime/Object.j
similarity index 100%
rename from Objective-J/Object.j
rename to Objective-J/Runtime/Object.j
diff --git a/Objective-J/bootstrap.js b/Objective-J/Runtime/bootstrap.js
similarity index 100%
rename from Objective-J/bootstrap.js
rename to Objective-J/Runtime/bootstrap.js
diff --git a/Objective-J/Runtime/build.xml b/Objective-J/Runtime/build.xml
new file mode 100644
index 000000000..4084587f5
--- /dev/null
+++ b/Objective-J/Runtime/build.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Objective-J/constants.js b/Objective-J/Runtime/constants.js
similarity index 100%
rename from Objective-J/constants.js
rename to Objective-J/Runtime/constants.js
diff --git a/Objective-J/debug.js b/Objective-J/Runtime/debug.js
similarity index 98%
rename from Objective-J/debug.js
rename to Objective-J/Runtime/debug.js
index 2d88c696c..9702e00c8 100644
--- a/Objective-J/debug.js
+++ b/Objective-J/Runtime/debug.js
@@ -119,7 +119,7 @@ function objj_backtrace_set_enabled(enabled)
function objj_debug_print_backtrace()
{
- CPLog.trace(objj_debug_backtrace_string());
+ print(objj_debug_backtrace_string());
}
function objj_debug_backtrace_string()
diff --git a/Objective-J/dictionary.js b/Objective-J/Runtime/dictionary.js
similarity index 100%
rename from Objective-J/dictionary.js
rename to Objective-J/Runtime/dictionary.js
diff --git a/Objective-J/evaluate.js b/Objective-J/Runtime/evaluate.js
similarity index 100%
rename from Objective-J/evaluate.js
rename to Objective-J/Runtime/evaluate.js
diff --git a/Objective-J/exception.js b/Objective-J/Runtime/exception.js
similarity index 100%
rename from Objective-J/exception.js
rename to Objective-J/Runtime/exception.js
diff --git a/Objective-J/file.js b/Objective-J/Runtime/file.js
similarity index 100%
rename from Objective-J/file.js
rename to Objective-J/Runtime/file.js
diff --git a/Objective-J/license.txt b/Objective-J/Runtime/license.txt
similarity index 100%
rename from Objective-J/license.txt
rename to Objective-J/Runtime/license.txt
diff --git a/Objective-J/plist.js b/Objective-J/Runtime/plist.js
similarity index 100%
rename from Objective-J/plist.js
rename to Objective-J/Runtime/plist.js
diff --git a/Objective-J/preprocess.js b/Objective-J/Runtime/preprocess.js
similarity index 100%
rename from Objective-J/preprocess.js
rename to Objective-J/Runtime/preprocess.js
diff --git a/Objective-J/Runtime/rakefile b/Objective-J/Runtime/rakefile
new file mode 100644
index 000000000..84b542598
--- /dev/null
+++ b/Objective-J/Runtime/rakefile
@@ -0,0 +1,65 @@
+#!/usr/bin/env ruby
+
+require 'rake'
+require '../../common'
+require 'objective-j'
+
+
+$PRODUCT = File.join($PRODUCT_DIR, 'Objective-J')
+$ENVIRONMENT_PRODUCT = File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J')
+
+$LICENSE_FILE = File.join($PRODUCT, 'LICENSE')
+$BROWSER_FILE = File.join($PRODUCT, 'Objective-J.js')
+$RHINO_FILE = File.join($PRODUCT, 'Rhino.platform', 'Objective-J.js')
+
+task :Products => [$BROWSER_FILE, $RHINO_FILE]
+
+task :build => [:Products, $ENVIRONMENT_PRODUCT]
+
+=begin
+task :environment => [$PRODUCT_FILE, $LICENSE_FILE, ENVIRONMENT_FRAMEWORKS_DIR] do
+ cp_r($BUILD_PRODUCT_DIR, ENVIRONMENT_FRAMEWORKS_DIR)
+end
+=end
+Files = [ 'LICENSE.txt',
+ 'constants.js',
+ 'utilities.js',
+ 'runtime.js',
+ 'dictionary.js',
+ 'plist.js',
+ 'file.js',
+ 'exception.js',
+ 'preprocess.js',
+ 'evaluate.js',
+ 'debug.js',
+ 'bootstrap.js'];
+
+file_d $BROWSER_FILE => Files do |t|
+ build_product(t.name)
+end
+
+file_d $RHINO_FILE => Files do |t|
+ build_product(t.name)
+end
+
+#Framework in environment directory
+file_d $ENVIRONMENT_PRODUCT => [:Products] do
+ cp_r($PRODUCT, $ENVIRONMENT_PRODUCT)
+end
+
+def build_product(path, *flags)
+
+ IO.popen("gcc -E -x c -P -", "w+") do |preprocessor|
+
+ Files.select { |name| name.match(/\.js$/) }.each do |fileName|
+ preprocessor.puts IO.read(fileName)
+ end
+
+ preprocessor.close_write
+
+ File.open(path, "w") do |file|
+ file.write(IO.read("LICENSE.txt") + preprocessor.read)
+ end
+
+ end
+end
diff --git a/Objective-J/runtime.js b/Objective-J/Runtime/runtime.js
similarity index 100%
rename from Objective-J/runtime.js
rename to Objective-J/Runtime/runtime.js
diff --git a/Objective-J/utilities.js b/Objective-J/Runtime/utilities.js
similarity index 100%
rename from Objective-J/utilities.js
rename to Objective-J/Runtime/utilities.js
diff --git a/Objective-J/Tools/build.xml b/Objective-J/Tools/build.xml
new file mode 100644
index 000000000..e084e2779
--- /dev/null
+++ b/Objective-J/Tools/build.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Objective-J/Tools/cplutil/build.xml b/Objective-J/Tools/cplutil/build.xml
new file mode 100644
index 000000000..ae799d33d
--- /dev/null
+++ b/Objective-J/Tools/cplutil/build.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Objective-J/Tools/cplutil/main.js b/Objective-J/Tools/cplutil/main.js
new file mode 100644
index 000000000..455df7a0f
--- /dev/null
+++ b/Objective-J/Tools/cplutil/main.js
@@ -0,0 +1,103 @@
+
+importPackage(java.lang);
+
+importClass(java.io.File);
+importClass(java.io.BufferedReader);
+importClass(java.io.FileReader);
+importClass(java.io.BufferedWriter);
+importClass(java.io.FileWriter);
+
+
+function printUsage()
+{
+ print("this is where you say the usage");
+}
+
+function main()
+{
+ if (arguments.length < 1)
+ return printUsage();
+
+ var allFiles = NO,
+ format = nil,
+ filePaths = [],
+ outPath = nil,
+ outExtension = nil;
+
+ index = 0,
+ count = arguments.length;
+
+ for (; index < count; ++index)
+ {
+ var argument = arguments[index];
+
+ if (argument.charAt(0) === '-' && !allFiles)
+ {
+ if (filePaths.length > 0)
+ return printUsage();
+
+ else if (argument === "-convert")
+ format = arguments[++index];
+
+ else if (argument === "-o")
+ outPath = arguments[++index];
+
+ else if (argument === "-e")
+ outExtension = arguments[++index];
+
+ else if (argument === "--")
+ allFiles = YES;
+
+ else if (argument === "-help")
+ return printUsage();
+ }
+ else
+ filePaths.push(arguments[index]);
+ }
+
+ index = 0;
+ count = filePaths.length;
+
+ for (; index < count; ++index)
+ {
+ // Read the plist file
+ var file = new File(filePaths[index]),
+ reader = new BufferedReader(new FileReader(file)),
+ fileContents = "";
+
+ // Get contents of the file
+ while (reader.ready())
+ fileContents += reader.readLine() + '\n';
+
+ reader.close();
+
+ var data = new objj_data();
+
+ data.string = fileContents;
+
+ var plistObject = new CPPropertyListCreateFromData(data);
+
+ if (format === "280north1")
+ data = CPPropertyListCreate280NorthData(plistObject);
+
+ else if (format === "xml1")
+ data = CPPropertyListCreateXMLData(plistObject);
+
+ var outFile = file;
+
+ if (outPath)
+ outFile = new File(outPath);
+
+// else if (outExtension)
+
+
+ // Write out file
+ var writer = new BufferedWriter(new FileWriter(outFile));
+
+ writer.write(data.string);
+
+ writer.close();
+ }
+}
+
+main.apply(main, arguments);
diff --git a/Tools/objj/objj b/Objective-J/Tools/executable
similarity index 88%
rename from Tools/objj/objj
rename to Objective-J/Tools/executable
index cb957fa6e..f2d87c461 100644
--- a/Tools/objj/objj
+++ b/Objective-J/Tools/executable
@@ -24,7 +24,7 @@ if [ -z $OBJJ_HOME ]; then
fi
OBJJ_LIB="$OBJJ_HOME/lib"
-CLASSPATH="$OBJJ_LIB:$OBJJ_LIB/js.jar:$CLASSPATH"
+CLASSPATH="$OBJJ_LIB:$OBJJ_LIB/js.jar:$OBJJ_HOME/lib/$(basename $SELF_PATH):$CLASSPATH"
OBJJ="$OBJJ_LIB/objj.js"
RLWRAP=`which rlwrap`
@@ -44,9 +44,9 @@ if [[ `uname` == CYGWIN* ]]; then
fi
export OBJJ_LIB
-
+echo $RLWRAP java -classpath $CLASSPATH main $@
#if [ -e $STEAM_BUILD/Objective-J.build/Release/Rhino ]; then
- $RLWRAP java -classpath $CLASSPATH objj $@
+ $RLWRAP java -classpath $CLASSPATH main $@
#$RLWRAP java -classpath $CLASSPATH org.mozilla.javascript.tools.shell.Main $OBJJ $@
#else
# echo "Missing frameworks at $STEAM_BUILD/Objective-J.build/Release/Rhino" 1>&2
diff --git a/Objective-J/Tools/objj/build.xml b/Objective-J/Tools/objj/build.xml
new file mode 100644
index 000000000..acc564d44
--- /dev/null
+++ b/Objective-J/Tools/objj/build.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tools/objj/objj.js b/Objective-J/Tools/objj/main.js
similarity index 96%
rename from Tools/objj/objj.js
rename to Objective-J/Tools/objj/main.js
index c1bb61a25..3dce72c56 100644
--- a/Tools/objj/objj.js
+++ b/Objective-J/Tools/objj/main.js
@@ -47,7 +47,7 @@ try
if (debug)
print("Loading: " + mainFilePath);
- objj_import(mainFilePath, YES);
+ objj_import(mainFilePath, YES, function() { if (typeof main === "Function") main.apply(main, args); } );
serviceTimeouts();
diff --git a/Objective-J/Tools/objj/rakefile b/Objective-J/Tools/objj/rakefile
new file mode 100644
index 000000000..83744b388
--- /dev/null
+++ b/Objective-J/Tools/objj/rakefile
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+
+require 'rake'
+require '../../../common'
+require 'objective-j'
+
+
+$OBJJ_SCRIPT = File.join($BUILD_DIR, 'objj.build', $CONFIGURATION, 'main-concat.js')
+$OBJJ_CLASS = File.join($ENVIRONMENT_LIB_DIR, 'objj', 'main.class')
+$OBJJ_EXECUTABLE = File.join($ENVIRONMENT_BIN_DIR, 'objj')
+$STANDARD_EXECUTABLE = File.expand_path(File.join('..', 'executable'))
+
+task :build => [$OBJJ_CLASS, $OBJJ_EXECUTABLE]
+
+Files = [ File.join($HOME_DIR, 'Tools', 'Utilities', 'bridge.js'), #yuck!
+ File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'Rhino.platform', 'Objective-J.js'),
+ 'main.js'];
+
+file_d $OBJJ_EXECUTABLE => [$STANDARD_EXECUTABLE] do
+ cp($STANDARD_EXECUTABLE, $OBJJ_EXECUTABLE)
+ File.chmod 0755, $OBJJ_EXECUTABLE
+end
+
+file_d $OBJJ_SCRIPT => Files do |t|
+ cat(Files, $OBJJ_SCRIPT)
+end
+
+file_d $OBJJ_CLASS => $OBJJ_SCRIPT do |t|
+ js2java($OBJJ_SCRIPT, 'main.class', false)
+ cp(File.join(File.dirname($OBJJ_SCRIPT), 'main.class'), $OBJJ_CLASS)
+end
diff --git a/Objective-J/Tools/objjc/build.xml b/Objective-J/Tools/objjc/build.xml
new file mode 100644
index 000000000..7838eaa21
--- /dev/null
+++ b/Objective-J/Tools/objjc/build.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tools/objjc/objjc.js b/Objective-J/Tools/objjc/main.js
similarity index 90%
rename from Tools/objjc/objjc.js
rename to Objective-J/Tools/objjc/main.js
index 8f737d0d5..2256ad544 100644
--- a/Tools/objjc/objjc.js
+++ b/Objective-J/Tools/objjc/main.js
@@ -90,7 +90,7 @@ function preprocess(aFilePath, outFilePath, gccArgs, flags)
// FIXME: figure out why this doesn't work on Windows/Cygwin
//var tmpFile = java.io.File.createTempFile("OBJJC", "");
- var tmpFile = new java.io.File(outFilePath+".tmp");
+ var tmpFile = new java.io.File(outFilePath + ".tmp");
tmpFile.deleteOnExit();
// -E JUST preprocess.
@@ -179,7 +179,7 @@ function main()
outFilePaths = [],
index = 0,
- count = args.length,
+ count = arguments.length,
gccArgs = [],
@@ -188,37 +188,38 @@ function main()
for (; index < count; ++index)
{
- if (args[index] == "-o")
+ var argument = String(arguments[index]);
+
+ if (argument === "-o")
{
if (++index < count)
- outFilePaths.push(args[index]);
+ outFilePaths.push(String(arguments[index]));
}
- else if (args[index].indexOf("-D") === 0)
- gccArgs.push(args[index])
+ else if (argument.indexOf("-D") === 0)
+ gccArgs.push(argument)
- else if (args[index].indexOf("-U") === 0)
- gccArgs.push(args[index]);
+ else if (argument.indexOf("-U") === 0)
+ gccArgs.push(argument);
- else if (args[index].indexOf("-E") === 0)
+ else if (argument.indexOf("-E") === 0)
flags &= ~OBJJ_PREPROCESSOR_PREPROCESS;
- else if (args[index].indexOf("-S") === 0)
+ else if (argument.indexOf("-S") === 0)
flags &= ~OBJJ_PREPROCESSOR_SYNTAX;
- else if (args[index].indexOf("-g") === 0)
+ else if (argument.indexOf("-g") === 0)
flags |= OBJJ_PREPROCESSOR_DEBUG_SYMBOLS;
- else if (args[index].indexOf("-O") === 0)
+ else if (argument.indexOf("-O") === 0)
flags |= OBJJ_PREPROCESSOR_COMPRESS;
else
- filePaths.push(args[index]);
+ filePaths.push(argument);
}
for (index = 0, count = filePaths.length; index < count; ++index)
preprocess(filePaths[index], outFilePaths[index], gccArgs, flags);
}
-args = arguments;
-main();
+main.apply(main, arguments);
diff --git a/Objective-J/Tools/objjc/rakefile b/Objective-J/Tools/objjc/rakefile
new file mode 100644
index 000000000..f2edbb35f
--- /dev/null
+++ b/Objective-J/Tools/objjc/rakefile
@@ -0,0 +1,37 @@
+#!/usr/bin/env ruby
+
+require 'rake'
+require '../../../common'
+require 'objective-j'
+
+
+$OBJJC_SCRIPT = File.join($BUILD_DIR, 'objjc.build', $CONFIGURATION, 'main-concat.js')
+$OBJJC_CLASS = File.join($ENVIRONMENT_LIB_DIR, 'objjc', 'main.class')
+$OBJJC_JS_COMPILER = File.join($ENVIRONMENT_LIB_DIR, 'objjc', 'shrinksafe.jar')
+$OBJJC_EXECUTABLE = File.join($ENVIRONMENT_BIN_DIR, 'objjc')
+$STANDARD_EXECUTABLE = File.expand_path(File.join('..', 'executable'))
+
+task :build => [$OBJJC_CLASS, $OBJJC_EXECUTABLE, $OBJJC_JS_COMPILER]
+
+Files = [ File.join($HOME_DIR, 'Tools', 'Utilities', 'bridge.js'), #yuck!
+ File.join($HOME_DIR, 'Tools', 'Utilities', 'regex-bridge.js'), #double-yuck!
+ File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'Rhino.platform', 'Objective-J.js'),
+ 'main.js'];
+
+file_d $OBJJC_EXECUTABLE => [$STANDARD_EXECUTABLE] do
+ cp($STANDARD_EXECUTABLE, $OBJJC_EXECUTABLE)
+ File.chmod 0755, $OBJJC_EXECUTABLE
+end
+
+file_d $OBJJC_SCRIPT => Files do
+ cat(Files, $OBJJC_SCRIPT)
+end
+
+file_d $OBJJC_CLASS => $OBJJC_SCRIPT do
+ js2java($OBJJC_SCRIPT, 'main.class', false)
+ cp(File.join(File.dirname($OBJJC_SCRIPT), 'main.class'), $OBJJC_CLASS)
+end
+
+file_d $OBJJC_JS_COMPILER => 'shrinksafe.jar' do
+ cp('shrinksafe.jar', $OBJJC_JS_COMPILER)
+end
diff --git a/Tools/objjc/shrinksafe.jar b/Objective-J/Tools/objjc/shrinksafe.jar
similarity index 100%
rename from Tools/objjc/shrinksafe.jar
rename to Objective-J/Tools/objjc/shrinksafe.jar
diff --git a/Objective-J/Tools/rakefile b/Objective-J/Tools/rakefile
new file mode 100644
index 000000000..9c0540866
--- /dev/null
+++ b/Objective-J/Tools/rakefile
@@ -0,0 +1,13 @@
+#!/usr/bin/env ruby
+
+require 'rake'
+require '../../common'
+
+
+subprojects = %w{objj objjc}
+
+%w(build clean).each do |task_name|
+ task task_name do
+ subrake(subprojects)
+ end
+end
diff --git a/Objective-J/Tools/steam/Project.js b/Objective-J/Tools/steam/Project.js
new file mode 100644
index 000000000..3e48b401c
--- /dev/null
+++ b/Objective-J/Tools/steam/Project.js
@@ -0,0 +1,331 @@
+
+importClass(java.io.FileOutputStream);
+importClass(java.io.BufferedWriter);
+importClass(java.io.OutputStreamWriter);
+
+function Target(dictionary)
+{
+ this._name = dictionary_getValue(dictionary, "Name");
+
+ var flagsString = dictionary_getValue(dictionary, "Flags");
+
+ this._flags = flagsString ? flagsString.split(/\s+/) : [];
+
+ this._type = dictionary_getValue(dictionary, "Type");
+
+ if (!this._type)
+ this._type = "280N.application";
+
+ this._exclusions = [];
+
+ var exclusions = dictionary_getValue(dictionary, "Excluded");
+
+ if (exclusions)
+ {
+ var index = 0,
+ count = exclusions.length;
+
+ for (; index < count; ++index)
+ this._exclusions.push(new File((exclusions[index])).getCanonicalFile());
+ }
+
+ return this;
+}
+
+Target.prototype.name = function()
+{
+ return this._name;
+}
+
+Target.prototype.exclusions = function()
+{
+ return this._exclusions;
+}
+
+Target.prototype.flags = function()
+{
+ return this._flags;
+}
+
+Target.prototype.type = function()
+{
+ return this._type;
+}
+
+function Configuration(dictionary)
+{
+ this._name = dictionary_getValue(dictionary, "Name");
+
+ var flagsString = dictionary_getValue(dictionary, "Flags");
+
+ this._flags = flagsString ? flagsString.split(/\s+/) : [];
+
+ return this;
+}
+
+Configuration.prototype.name = function()
+{
+ return this._name;
+}
+
+Configuration.prototype.flags = function()
+{
+ return this._flags;
+}
+
+function Project(/*String*/ aFilePath, /*String*/ aBuildPath)
+{
+ this._file = new File(aFilePath).getCanonicalFile();
+ this._root = this._file.getParentFile();
+
+ // Read the project file (its just a plist).
+ this._properties = readPlist(this._file);
+
+ this._name = dictionary_getValue(this._properties, "Name");
+
+ // Read existing Info.plist if it exists.
+ var infoPlist = new File(this._root.getAbsolutePath() + "/Info.plist");
+
+ if (infoPlist.exists())
+ this._infoDictionary = readPlist(new File(this._root.getAbsolutePath() + "/Info.plist"));
+ else
+ this._infoDictionary = new objj_dictionary();
+
+ this.buildPath = aBuildPath;
+
+ // Covert target dictionaries to target objects.
+ var targetDictionaries = dictionary_getValue(this._properties, "Targets");
+
+ this._targets = [];
+
+ for (var index = 0, count = targetDictionaries.length; index < count; ++index)
+ this._targets.push(new Target(targetDictionaries[index]));
+
+ this.setActiveTarget(this._targets[0]);
+
+ // Covert target dictionaries to target objects.
+ var configurationDictionaries = dictionary_getValue(this._properties, "Configurations");
+
+ this._configurations = [];
+
+ for (index = 0, count = configurationDictionaries.length; index < count; ++index)
+ this._configurations.push(new Configuration(configurationDictionaries[index]));
+
+ this.setActiveConfiguration(this._configurations[0]);
+
+ // Grab the Resources Directory (if it exists)
+ this._resources = new File(this._root.getAbsolutePath() + "/Resources/").getCanonicalFile();
+
+ return this;
+}
+
+Project.prototype.name = function()
+{
+ return this._name;
+}
+
+Project.prototype.targetWithName = function(/*String*/ aName)
+{
+ var targets = this._targets,
+ index = 0,
+ count = targets.length;
+
+ for (; index < count; ++index)
+ {
+ var target = targets[index];
+
+ if (target.name() == aName)
+ return target;
+ }
+
+ return null;
+}
+
+Project.prototype.configurationWithName = function(/*String*/ aName)
+{
+ var configurations = this._configurations,
+ index = 0,
+ count = configurations.length;
+
+ for (; index < count; ++index)
+ {
+ var configuration = configurations[index];
+
+ if (configuration.name() == aName)
+ return configuration;
+ }
+
+ return null;
+}
+
+Project.prototype.setActiveTarget = function(/*Target*/ aTarget)
+{
+ this._activeTarget = aTarget;
+
+ this._buildProducts = null;
+ this._buildIntermediates = null;
+ this._buildObjects = null;
+}
+
+Project.prototype.activeTarget = function()
+{
+ return this._activeTarget;
+}
+
+Project.prototype.setActiveConfiguration = function(/*Configuration*/ aConfiguration)
+{
+ this._activeConfiguration = aConfiguration;
+
+ this._buildProducts = null;
+ this._buildIntermediates = null;
+ this._buildObjects = null;
+}
+
+Project.prototype.activeConfiguration = function()
+{
+ return this._activeConfiguration;
+}
+
+Project.prototype.buildProducts = function()
+{
+ if (!this._buildProducts)
+ {
+ this._buildProducts = new File(this.buildPath + '/' + this._activeConfiguration.name() + '/' + this._activeTarget.name()).getCanonicalFile();
+ this._buildProducts.mkdirs();
+ }
+
+ return this._buildProducts;
+}
+
+Project.prototype.buildIntermediates = function()
+{
+ if (!this._buildIntermediates)
+ {
+ this._buildIntermediates = new File(this.buildPath + '/' + this._activeTarget.name() + ".build/" + this._activeConfiguration.name()).getCanonicalFile();
+ this._buildIntermediates.mkdirs();
+ }
+
+ return this._buildIntermediates;
+}
+
+Project.prototype.buildObjects = function()
+{
+ if (!this._buildObjects)
+ {
+ this._buildObjects = new File(this.buildIntermediates().getAbsolutePath() + '/' + this._activeTarget.name()).getCanonicalFile();
+ this._buildObjects.mkdirs();
+ }
+
+ return this._buildObjects;
+}
+
+Project.prototype.activeFlags = function()
+{
+ return this.activeTarget().flags().concat(this.activeConfiguration().flags());
+}
+
+Project.prototype.build = function()
+{
+ java.lang.System.out.println("Building Target \"" + this.activeTarget().name() +
+ "\" of Project \"" + this.name() +
+ "\" with Configuration \"" + this.activeConfiguration().name() + "\".");
+
+ var jFiles = getFiles(this._root, "j", this._activeTarget.exclusions()),
+ replacedFiles = [];
+ hasModifiedJFiles = false;
+ shouldObjjPreprocess = true,
+ shouldGzip = this._gzip,
+ objjcComponents = ["sh", OBJJ_HOME + "/bin/objjc"];
+
+ objjcComponents = objjcComponents.concat(this.activeFlags());
+
+ if (!shouldObjjPreprocess)
+ objjcComponents.push("-E");
+
+ var buildObjects = this.buildObjects(),
+ buildProducts = this.buildProducts();
+
+ for (index = 0, count = jFiles.length; index < count; ++index)
+ {
+ var file = jFiles[index],
+ builtFile = new File(buildObjects.getAbsolutePath() + '/' + getFileNameWithoutExtension(file) + '.o');
+
+ replacedFiles.push(file.getName() + "");
+
+ if (builtFile.exists() && file.lastModified() < builtFile.lastModified())
+ continue;
+ else
+ hasModifiedJFiles = true;
+
+ objjcComponents.push(file.getAbsolutePath());
+
+ objjcComponents.push("-o");
+ objjcComponents.push(buildObjects.getAbsolutePath() + '/' + getFileNameWithoutExtension(file) + '.o');
+ }
+
+ exec(objjcComponents, true);
+
+ var oFiles = getFiles(buildObjects, 'o'),
+ sjFile = new File(buildProducts.getCanonicalPath() + '/' + this._activeTarget.name() + ".sj");
+
+ if (hasModifiedJFiles)
+ {
+ // concatenate sjheader.txt and individual .o
+ exec(["sh", "-c", "cat '" + OBJJ_STEAM + "/sjheader.txt' '" + oFiles.join("' '") + "' > '" + sjFile.getCanonicalPath() + "'"], true);
+ }
+
+ if (shouldGzip)
+ {
+ // gzip and copy .htaccess file
+ exec(["sh", "-c", "gzip -c '" + sjFile.getCanonicalPath() + "' > '" + sjFile.getCanonicalPath() + ".gz'"], true);
+ exec(["cp", OBJJ_HOME + "/lib/htaccess", sjFile.getParentFile().getCanonicalPath() + "/.htaccess"], true);
+ }
+ else
+ {
+ // remove gzip and .htaccess file if present
+ exec(["rm", "-f", sjFile.getParentFile().getCanonicalPath() + "/.htaccess", sjFile.getCanonicalPath() + ".gz"], true);
+ }
+
+ dictionary_setValue(this._infoDictionary, "CPBundleExecutable", this._activeTarget.name() + ".sj");
+ dictionary_setValue(this._infoDictionary, "CPBundleReplacedFiles", replacedFiles);
+
+ this.writeInfoPlist();
+
+ this.copyResources();
+
+ // FIXME: This should be, if this is an app...
+ if (dictionary_getValue(this._infoDictionary, "CPBundlePackageType") == "280N")
+ this.copyIndexFile();
+
+}
+
+Project.prototype.clean = function()
+{
+ java.lang.System.out.println("Cleaning Target \"" + this.activeTarget().name() +
+ "\" of Project \"" + this.name() +
+ "\" with Configuration \"" + this.activeConfiguration().name() + "\".");
+
+ exec(["rm", "-rf", this.buildIntermediates().getAbsolutePath()], true);
+ exec(["rm", "-rf", this.buildProducts().getAbsolutePath()], true);
+}
+
+Project.prototype.copyIndexFile = function()
+{
+ var indexFile = new File(this._root.getAbsolutePath() + "/index.html").getCanonicalFile();
+
+ rsync(indexFile, this.buildProducts());
+}
+
+Project.prototype.writeInfoPlist = function()
+{
+ var writer = new BufferedWriter(new FileWriter(this.buildProducts().getAbsolutePath() + '/' + "Info.plist"));
+
+ writer.write(CPPropertyListCreateXMLData(this._infoDictionary).string);
+
+ writer.close();
+}
+
+Project.prototype.copyResources = function()
+{
+ rsync(this._resources, this.buildProducts());
+}
diff --git a/Objective-J/Tools/steam/Templates/Application/AppController.j b/Objective-J/Tools/steam/Templates/Application/AppController.j
new file mode 100644
index 000000000..21ede646e
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/Application/AppController.j
@@ -0,0 +1,39 @@
+/*
+ * AppController.j
+ * __Product__
+ *
+ * Created by __Me__ on __Date__.
+ * Copyright 2008 __MyCompanyName__. All rights reserved.
+ */
+
+@import
+
+
+@implementation AppController : CPObject
+{
+}
+
+- (void)applicationDidFinishLaunching:(CPNotification)aNotification
+{
+ var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
+ contentView = [theWindow contentView];
+
+ var label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
+
+ [label setStringValue:@"Hello World!"];
+ [label setFont:[CPFont boldSystemFontOfSize:24.0]];
+
+ [label sizeToFit];
+
+ [label setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin | CPViewMinYMargin | CPViewMaxYMargin];
+ [label setFrameOrigin:CGPointMake((CGRectGetWidth([contentView bounds]) - CGRectGetWidth([label frame])) / 2.0, (CGRectGetHeight([contentView bounds]) - CGRectGetHeight([label frame])) / 2.0)];
+
+ [contentView addSubview:label];
+
+ [theWindow orderFront:self];
+
+ // Uncomment the following line to turn on the standard menu bar.
+ //[CPMenu setMenuBarVisible:YES];
+}
+
+@end
diff --git a/Objective-J/Tools/steam/Templates/Application/Info.plist b/Objective-J/Tools/steam/Templates/Application/Info.plist
new file mode 100644
index 000000000..a81852dcd
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/Application/Info.plist
@@ -0,0 +1,12 @@
+
+
+
+
+ CPApplicationDelegateClass
+ AppController
+ CPBundleName
+ __Product__
+ CPPrincipalClass
+ CPApplication
+
+
diff --git a/Objective-J/Tools/steam/Templates/Application/index-debug.html b/Objective-J/Tools/steam/Templates/Application/index-debug.html
new file mode 100644
index 000000000..d941b006a
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/Application/index-debug.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+ Hello World
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Objective-J/Tools/steam/Templates/Application/index.html b/Objective-J/Tools/steam/Templates/Application/index.html
new file mode 100644
index 000000000..bea6f5f36
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/Application/index.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ Hello World
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Objective-J/Tools/steam/Templates/Application/main.j b/Objective-J/Tools/steam/Templates/Application/main.j
new file mode 100755
index 000000000..d4cec69f3
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/Application/main.j
@@ -0,0 +1,18 @@
+/*
+ * main.j
+ * __Product__
+ *
+ * Created by __Me__ on __Date__.
+ * Copyright 2008 __MyCompanyName__. All rights reserved.
+ */
+
+@import
+@import
+
+@import "AppController.j"
+
+
+function main(args, namedArgs)
+{
+ CPApplicationMain(args, namedArgs);
+}
diff --git a/Objective-J/Tools/steam/Templates/ThemeDescriptor/Info.plist b/Objective-J/Tools/steam/Templates/ThemeDescriptor/Info.plist
new file mode 100644
index 000000000..f09701c61
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/ThemeDescriptor/Info.plist
@@ -0,0 +1,12 @@
+
+
+
+
+ CPApplicationDelegateClass
+ BKShowcaseController
+ CPBundleName
+ __Product__
+ CPPrincipalClass
+ CPApplication
+
+
diff --git a/Objective-J/Tools/steam/Templates/ThemeDescriptor/ThemeDescriptors.j b/Objective-J/Tools/steam/Templates/ThemeDescriptor/ThemeDescriptors.j
new file mode 100644
index 000000000..aab4c6581
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/ThemeDescriptor/ThemeDescriptors.j
@@ -0,0 +1,33 @@
+/*
+ * ThemeDescriptors.j
+ * __Product__
+ *
+ * Created by __Me__ on __Date__.
+ * Copyright 2008 __MyCompanyName__. All rights reserved.
+ */
+
+@import
+
+
+@implementation __Product__ThemeDescriptor : CPObject
+{
+}
+
++ (CPString)themeName
+{
+ return @"__Product__";
+}
+
++ (CPTextField)themedTextField
+{
+ var textField = [[CPTextField alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 20.0)];
+
+ [textField setValue:[CPColor blueColor] forThemedAttributeName:@"bezel-color"];
+ [textField setValue:[CPColor redColor] forThemedAttributeName:@"text-color"];
+
+ [textField setStringValue:@"Yikes!"];
+
+ return textField;
+}
+
+@end
diff --git a/Objective-J/Tools/steam/Templates/ThemeDescriptor/index-debug.html b/Objective-J/Tools/steam/Templates/ThemeDescriptor/index-debug.html
new file mode 100644
index 000000000..d941b006a
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/ThemeDescriptor/index-debug.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+ Hello World
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Objective-J/Tools/steam/Templates/ThemeDescriptor/index.html b/Objective-J/Tools/steam/Templates/ThemeDescriptor/index.html
new file mode 100644
index 000000000..bea6f5f36
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/ThemeDescriptor/index.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ Hello World
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Objective-J/Tools/steam/Templates/ThemeDescriptor/main.j b/Objective-J/Tools/steam/Templates/ThemeDescriptor/main.j
new file mode 100755
index 000000000..cb02f4859
--- /dev/null
+++ b/Objective-J/Tools/steam/Templates/ThemeDescriptor/main.j
@@ -0,0 +1,19 @@
+/*
+ * main.j
+ * __Product__
+ *
+ * Created by __Me__ on __Date__.
+ * Copyright 2008 __MyCompanyName__. All rights reserved.
+ */
+
+@import
+@import
+@import
+
+@import "ThemeDescriptors.j"
+
+
+function main(args, namedArgs)
+{
+ CPApplicationMain(args, namedArgs);
+}
diff --git a/Objective-J/Tools/steam/build.js b/Objective-J/Tools/steam/build.js
new file mode 100644
index 000000000..042decf11
--- /dev/null
+++ b/Objective-J/Tools/steam/build.js
@@ -0,0 +1,102 @@
+function build()
+{
+ var index = 0,
+ count = arguments.length,
+
+ actions = [],
+
+ targetName = null,
+ configurationName = null,
+
+ buildPath = null,
+ projectFilePath = null,
+
+ gzip = false;
+
+ for (; index < count; ++index)
+ {
+ switch (arguments[index])
+ {
+ case "-f": if (index + 1 == count)
+ throw "-f needs project file.";
+
+ projectFilePath = arguments[++index];
+ break;
+
+ case "-t": if (index + 1 == count)
+ throw "-t needs a target";
+
+ targetName = arguments[++index];
+ break;
+
+ case "-c": if (index + 1 == count)
+ throw "-c needs configuration";
+
+ configurationName = arguments[++index];
+ break;
+
+ case "-b": if (index + 1 == count)
+ throw "-b needs a build location";
+
+ buildPath = arguments[++index];
+ break;
+
+ case "--gzip": gzip = true;
+ break;
+
+ case "clean":
+ case "build": actions.push(arguments[index]);
+ break;
+ }
+ }
+
+ // If no project file was specified, look for one.
+ if (!projectFilePath)
+ {
+ var candidates = getFiles(new File('.'), "steam");
+
+ if (candidates.length < 1)
+ throw "No project file specified or found.";
+
+ projectFilePath = candidates[0];
+ }
+
+ // Construct the Build Directory
+ if (!buildPath)
+ {
+ buildPath = System.getenv("STEAM_BUILD");
+
+ if (!buildPath)
+ buildPath = "Build";
+ }
+
+ var project = new Project(projectFilePath, buildPath);
+
+ project._gzip = gzip;
+
+ if (targetName)
+ {
+ var target = project.targetWithName(targetName);
+
+ if (!target)
+ throw "Target \"" + targetName + "\" not found in project.";
+
+ project.setActiveTarget(target);
+ }
+
+ if (configurationName)
+ {
+ var configuration = project.configurationWithName(configurationName);
+
+ if (!configuration)
+ throw "Configuration \"" + configurationName + "\" not found in project.";
+
+ project.setActiveConfiguration(configuration);
+ }
+
+ if (!actions.length)
+ actions.push("build");
+
+ for (index = 0, count = actions.length; index < count; ++index)
+ project[actions[index]]();
+}
diff --git a/Objective-J/Tools/steam/build.xml b/Objective-J/Tools/steam/build.xml
new file mode 100644
index 000000000..568809646
--- /dev/null
+++ b/Objective-J/Tools/steam/build.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Objective-J/Tools/steam/create-frameworks.js b/Objective-J/Tools/steam/create-frameworks.js
new file mode 100644
index 000000000..89b355ea9
--- /dev/null
+++ b/Objective-J/Tools/steam/create-frameworks.js
@@ -0,0 +1,66 @@
+function createFrameworks()
+{
+ var shouldSymbolicallyLink = false,
+ index = 0,
+ count = arguments.length,
+
+ destination = "";
+
+ for (; index < count; ++index)
+ {
+ var argument = arguments[index];
+
+ switch (arguments[index])
+ {
+ case "-l": shouldSymbolicallyLink = true;
+ break;
+
+ default: destination = argument;
+ }
+ }
+
+ createFrameworksInFile(new File(destination), shouldSymbolicallyLink);
+}
+
+function createFrameworksInFile(/*File*/ aFile, /*Boolean*/ shouldSymbolicallyLink)
+{
+ var destinationFrameworks = new File(aFile.getCanonicalPath()+ "/Frameworks"),
+ destinationDebugFrameworks = new File(aFile.getCanonicalPath() + "/Frameworks/Debug");
+
+ if (!shouldSymbolicallyLink)
+ {
+ var sourceFrameworks = new File(OBJJ_HOME + "/lib/Frameworks"),
+ sourceDebugFrameworks = new File(OBJJ_HOME + "/lib/Frameworks-Debug");
+
+ exec(["cp", "-vR", sourceFrameworks.getCanonicalPath(), destinationFrameworks.getCanonicalPath()], true);
+ exec(["cp", "-vR", sourceDebugFrameworks.getCanonicalPath(), destinationDebugFrameworks.getCanonicalPath()], true);
+
+ return true;
+ }
+
+ var STEAM_BUILD = System.getenv("STEAM_BUILD");
+
+ // Release Frameworks
+ new File(destinationFrameworks).mkdir();
+
+ exec(["ln", "-s", new File(STEAM_BUILD + "/Release/Objective-J").getCanonicalPath(),
+ new File(aFile.getCanonicalPath() + "/Frameworks/Objective-J").getCanonicalPath()], true);
+
+ exec(["ln", "-s", new File(STEAM_BUILD + "/Release/Foundation").getCanonicalPath(),
+ new File(aFile.getCanonicalPath() + "/Frameworks/Foundation").getCanonicalPath()], true);
+
+ exec(["ln", "-s", new File(STEAM_BUILD + "/Release/AppKit").getCanonicalPath(),
+ new File(aFile.getCanonicalPath() + "/Frameworks/AppKit").getCanonicalPath()], true);
+
+ // Debug Frameworks
+ new File(destinationDebugFrameworks).mkdir();
+
+ exec(["ln", "-s", new File(STEAM_BUILD + "/Debug/Objective-J").getCanonicalPath(),
+ new File(aFile.getCanonicalPath() + "/Frameworks/Debug/Objective-J").getCanonicalPath()], true);
+
+ exec(["ln", "-s", new File(STEAM_BUILD + "/Debug/Foundation").getCanonicalPath(),
+ new File(aFile.getCanonicalPath() + "/Frameworks/Debug/Foundation").getCanonicalPath()], true);
+
+ exec(["ln", "-s", new File(STEAM_BUILD + "/Debug/AppKit").getCanonicalPath(),
+ new File(aFile.getCanonicalPath() + "/Frameworks/Debug/AppKit").getCanonicalPath()], true);
+}
\ No newline at end of file
diff --git a/Objective-J/Tools/steam/create.js b/Objective-J/Tools/steam/create.js
new file mode 100644
index 000000000..73abaa8dc
--- /dev/null
+++ b/Objective-J/Tools/steam/create.js
@@ -0,0 +1,54 @@
+function create()
+{
+ if (arguments.length < 1)
+ printUsage("create");
+
+ var shouldSymbolicallyLink = false,
+ index = 0,
+ count = arguments.length,
+
+ template = "Application",
+ destination = "";
+
+ for (; index < count; ++index)
+ {
+ var argument = arguments[index];
+
+ switch (arguments[index])
+ {
+ case "-l": shouldSymbolicallyLink = true;
+ break;
+
+ case "--template": template = arguments[++index];
+ break;
+
+ default: destination = argument;
+ }
+ }
+
+ var sourceTemplate = new File(OBJJ_HOME + "/lib/steam/Templates/" + template),
+ destinationProject = new File(destination);
+
+ if (!destinationProject.exists())
+ {
+ exec(["cp", "-vR", sourceTemplate.getCanonicalPath(), destinationProject.getCanonicalPath()], true);
+
+ var files = getFiles(destinationProject, ['j', "plist", "html"]),
+ index = 0,
+ count = files.length;
+
+ for (; index < count; ++index)
+ {
+ var file = files[index],
+ contents = readFile(file);
+
+ contents = contents.replace(/__Product__/g, destinationProject.getName());
+
+ writeContentsToFile(contents, file);
+ }
+
+ createFrameworksInFile(destinationProject, shouldSymbolicallyLink);
+ }
+ else
+ System.out.println("Directory already exists");
+}
diff --git a/Objective-J/Tools/steam/htaccess b/Objective-J/Tools/steam/htaccess
new file mode 100644
index 000000000..6afc67f10
--- /dev/null
+++ b/Objective-J/Tools/steam/htaccess
@@ -0,0 +1,12 @@
+Options +FollowSymLinks
+
+AddEncoding x-gzip .gz
+AddType text/plain .gz
+
+RewriteEngine on
+
+# These conditions slow down the requests significantly. We can probably assume they're always true.
+# We should ensure the gzipped version always exists if we include this .htaccess. All supported browsers accept gzip encoding.
+#RewriteCond %{REQUEST_FILENAME}.gz -f
+#RewriteCond %{HTTP:Accept-Encoding} gzip
+RewriteRule ^(.*\.(sj|js))$ %{REQUEST_URI}/../$1.gz
diff --git a/Objective-J/Tools/steam/inline-bundle.js b/Objective-J/Tools/steam/inline-bundle.js
new file mode 100644
index 000000000..2e2dc8643
--- /dev/null
+++ b/Objective-J/Tools/steam/inline-bundle.js
@@ -0,0 +1,156 @@
+function inlineBundle()
+{
+ var index = 0,
+ count = arguments.length,
+ bundlePath = NULL;
+
+ for (; index < count; ++index)
+ {
+ var argument = arguments[index];
+
+ switch (arguments[index])
+ {
+ case "-d": directoryPath = arguments[++index];
+ break;
+
+ default: bundlePath = argument;
+ }
+ }
+
+ var bundleFile = new File(bundlePath).getCanonicalFile(),
+ bundlePath = String(bundleFile.getCanonicalPath()),
+ inlinedBundle = readBundle(bundleFile, true),
+ inlinedFiles = [],
+ replacedFiles = [],
+ staticContent = "";
+
+ // Find all internal bundles.
+ var bundleCandidates = getFiles(bundleFile, "plist"),
+ bundleCandidatesCount = bundleCandidates.length;
+
+ while (bundleCandidatesCount--)
+ {
+ var bundleCandidate = bundleCandidates[bundleCandidatesCount];
+
+ // We only care about Info.plists, specifically the ones that aren't us.
+ if (String(bundleCandidate.getName()) !== "Info.plist" || String(bundleCandidate.getCanonicalPath()) === inlinedBundle.path)
+ continue;
+
+ var infoDictionary = readPlist(bundleCandidate);
+
+ // At least one of these two has to be present for this to be a real deal bundle.
+ if (!dictionary_getValue(infoDictionary, "CPBundleIdentifier") && !dictionary_getValue(infoDictionary, "CPBundleName"))
+ continue;
+
+ java.lang.System.out.println(" Examining " + pathRelativeTo(bundleCandidate.getCanonicalPath(), bundlePath));
+
+ dictionary_removeValue(infoDictionary, "CPBundleExecutable");
+
+ var bundle = readBundle(bundleCandidate.getParentFile(), true);
+
+ bundle.path = pathRelativeTo(bundle.path, bundlePath);
+
+ // We want to inline the info plist too.
+ var inlinedFiles = [makeOBJJPlistFile(infoDictionary, bundleCandidate, bundle)].concat(bundle.files),
+ index = 0,
+ count = inlinedFiles.length;
+
+ for (; index < count; ++index)
+ {
+ var file = inlinedFiles[index];
+
+ file.path = pathRelativeTo(String(file.path), bundlePath);
+
+ java.lang.System.out.println(" Inlining " + file.path);
+
+ replacedFiles.push(file.path);
+ staticContent += fileToMarkedString(inlinedFiles[index], true);
+ }
+ }
+
+ var index = 0,
+ existingStaticFiles = inlinedBundle.files,
+ count = existingStaticFiles.length,
+ topLevelContent = "@STATIC;1.0;";
+
+ for (; index < count; ++index)
+ {
+ var file = existingStaticFiles[index];
+
+ // If this isn't actually part of our bundle, drop it!
+ if (file.bundle !== inlinedBundle)
+ continue;
+
+ file.path = pathRelativeTo(String(file.path), bundlePath);
+
+ replacedFiles.push(file.path);
+ topLevelContent += fileToMarkedString(file, false);
+ }
+
+ dictionary_setValue(inlinedBundle.info, "CPBundleReplacedFiles", replacedFiles);
+
+ writeContentsToFile(CPPropertyListCreateXMLData(inlinedBundle.info).string, inlinedBundle.path);
+ writeContentsToFile(topLevelContent + staticContent, inlinedBundle._staticContentPath);
+}
+
+function fileToMarkedString(anOBJJFile, encodeBundle)
+{
+ var markedString = "";
+
+ markedString += MARKER_PATH + ';' + anOBJJFile.path.length + ';' + anOBJJFile.path;
+
+ if (encodeBundle)
+ markedString += MARKER_BUNDLE + ';' + anOBJJFile.bundle.path.length + ';' + anOBJJFile.bundle.path;
+
+ var fragments = anOBJJFile.fragments;
+
+ if (fragments && fragments.length > 0)
+ {
+ var fragmentIndex = 0,
+ fragmentCount = fragments.length;
+
+ for (; fragmentIndex < fragmentCount; ++fragmentIndex)
+ markedString += fragments[fragmentIndex].toMarkedString();
+ }
+
+ else
+ markedString += MARKER_TEXT + ';' + anOBJJFile.contents.length + ';' + anOBJJFile.contents;
+
+ return markedString;
+}
+
+function makeOBJJPlistFile(aDictionary, aFile, aBundle)
+{
+ var file = new objj_file();
+
+ file.path = typeof aFile === "string" ? aFile : aFile.getCanonicalPath();
+ file.bundle = aBundle;
+ file.contents = CPPropertyListCreate280NorthData(aDictionary).string;
+
+ return file;
+}
+
+function pathRelativeTo(target, relativeTo)
+{
+ var components = [],
+ targetParts = target.split("/"),
+ relativeParts = relativeTo ? relativeTo.split("/") : [];
+
+ var i = 0;
+ while (i < targetParts.length)
+ {
+ if (targetParts[i] != relativeParts[i])
+ break;
+ i++;
+ }
+
+ for (var j = i; j < relativeParts.length; j++)
+ components.push("..");
+
+ for (var j = i; j < targetParts.length; j++)
+ components.push(targetParts[j]);
+
+ var result = components.join("/");
+
+ return result;
+}
\ No newline at end of file
diff --git a/Objective-J/Tools/steam/main.js b/Objective-J/Tools/steam/main.js
new file mode 100644
index 000000000..d007905f7
--- /dev/null
+++ b/Objective-J/Tools/steam/main.js
@@ -0,0 +1,203 @@
+
+importPackage(java.lang);
+importPackage(java.util);
+
+importClass(java.io.File);
+importClass(java.io.BufferedReader);
+importClass(java.io.FileReader);
+importClass(java.io.BufferedWriter);
+importClass(java.io.FileWriter);
+importClass(java.io.SequenceInputStream);
+
+#include "../Utilities/bundle.js"
+
+#include "Project.js"
+
+OBJJ_STEAM = OBJJ_HOME + "/lib/steam/";
+
+function main()
+{
+ if (arguments.length < 1)
+ printUsage();
+
+ var command = Array.prototype.shift.apply(arguments);
+
+ switch (command)
+ {
+ case "create": create.apply(create, arguments);
+ break;
+
+ case "create-frameworks": createFrameworks.apply(createFrameworks, arguments);
+ break;
+
+
+ case "inline-bundle": inlineBundle.apply(inlineBundle, arguments);
+ break;
+
+ case "build": build.apply(build, arguments);
+ break;
+
+ case "help": printUsage(arguments[1]);
+ break;
+
+ case "version":
+ case "--version": printVersion();
+ break;
+
+ default : printUsage(command);
+ }
+
+}
+
+function fileArrayContainsFile(/*Array*/ files, /*File*/ aFile)
+{
+ var index = 0,
+ count = files.length;
+
+ for (; index < count; ++index)
+ if (files[index].equals(aFile))
+ return true;
+
+ return false;
+}
+
+function getFiles(/*File*/ sourceDirectory, /*nil|String|Array*/ extensions, /*Array*/ exclusions)
+{
+ var matches = [],
+ files = sourceDirectory.listFiles(),
+ hasMultipleExtensions = typeof extensions !== "string";
+
+ if (files)
+ {
+ var index = 0,
+ count = files.length;
+
+ for (; index < count; ++index)
+ {
+ var file = files[index].getCanonicalFile(),
+ name = String(file.getName()),
+ isValidExtension = !extensions;
+
+ if (exclusions && fileArrayContainsFile(exclusions, file))
+ continue;
+
+ if (!isValidExtension)
+ if (hasMultipleExtensions)
+ {
+ var extensionCount = extensions.length;
+
+ while (extensionCount-- && !isValidExtension)
+ {
+ var extension = extensions[extensionCount];
+
+ if (name.substring(name.length - extension.length - 1) === ("." + extension))
+ isValidExtension = true;
+ }
+ }
+ else if (name.substring(name.length - extensions.length - 1) === ("." + extensions))
+ isValidExtension = true;
+
+ if (isValidExtension)
+ matches.push(file);
+
+ if (file.isDirectory())
+ matches = matches.concat(getFiles(file, extensions, exclusions));
+ }
+ }
+
+ return matches;
+}
+
+function exec(/*Array*/ command, /*Boolean*/ showOutput)
+{
+ var line = "",
+ output = "",
+
+ process = Packages.java.lang.Runtime.getRuntime().exec(command),//jsArrayToJavaArray(command));
+ reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getInputStream()));
+
+ while (line = reader.readLine())
+ {
+ if (showOutput)
+ System.out.println(line);
+
+ output += line + '\n';
+ }
+
+ reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getErrorStream()));
+
+ while (line = reader.readLine())
+ System.out.println(line);
+
+ try
+ {
+ if (process.waitFor() != 0)
+ System.err.println("exit value = " + process.exitValue());
+ }
+ catch (anException)
+ {
+ System.err.println(anException);
+ }
+
+ return output;
+}
+
+function rsync(srcFile, dstFile)
+{
+ var src, dst;
+
+ if (String(java.lang.System.getenv("OS")).indexOf("Windows") < 0)
+ {
+ src = srcFile.getAbsolutePath();
+ dst = dstFile.getAbsolutePath();
+ }
+ else
+ {
+ src = exec(["cygpath", "-u", srcFile.getAbsolutePath() + '/']);
+ dst = exec(["cygpath", "-u", dstFile.getAbsolutePath() + "/Resources"]);
+ }
+
+ if (srcFile.exists())
+ exec(["rsync", "-avz", src, dst]);
+}
+
+function getFileName(aPath)
+{
+ var index = aPath.lastIndexOf('/');
+
+ if (index == -1)
+ return aPath;
+
+ return aPath.substr(index + 1);
+}
+
+function getFileNameWithoutExtension(aFileOrFileName)
+{
+ var name = typeof aFileOrFileName === "string" ? aFileOrFileName : aFileOrFileName.getName(),
+ index = name.lastIndexOf('.');
+
+ if (index == -1 || index == 0)
+ return name;
+
+ return name.substr(0, index);
+}
+
+function getFileExtension(aPath)
+{
+ var slash = aPath.lastIndexOf('/'),
+ period = aPath.lastIndexOf('.');
+
+ if (period < slash || (period == slash + 1))
+ return "";
+
+ return aPath.substr(period + 1);
+}
+
+main.apply(main, arguments);
+
+#include "build.js"
+#include "create.js"
+#include "create-frameworks.js"
+#include "inline-bundle.js"
+#include "usage.js"
+#include "version.js"
diff --git a/Objective-J/Tools/steam/sjheader.txt b/Objective-J/Tools/steam/sjheader.txt
new file mode 100644
index 000000000..57390737c
--- /dev/null
+++ b/Objective-J/Tools/steam/sjheader.txt
@@ -0,0 +1 @@
+@STATIC;1.0;
\ No newline at end of file
diff --git a/Tools/objjc/objjc b/Objective-J/Tools/steam/steam
similarity index 83%
rename from Tools/objjc/objjc
rename to Objective-J/Tools/steam/steam
index 69db5ed63..e66147478 100644
--- a/Tools/objjc/objjc
+++ b/Objective-J/Tools/steam/steam
@@ -24,11 +24,15 @@ if [ -z $OBJJ_HOME ]; then
fi
OBJJ_LIB="$OBJJ_HOME/lib"
-CLASSPATH="$OBJJ_LIB:$OBJJ_LIB/js.jar"
+STEAM="$OBJJ_LIB/steam"
+CLASSPATH="$STEAM:$OBJJ_LIB:$OBJJ_LIB/js.jar"
# convert paths for Cygwin
if [[ `uname` == CYGWIN* ]]; then
CLASSPATH=`cygpath -wp "$CLASSPATH"`
+ STEAM_BUILD=`cygpath -wp "$STEAM_BUILD"`
fi
-java -classpath $CLASSPATH objjc $@
+export OBJJ_LIB
+
+java -classpath $CLASSPATH steam $@
diff --git a/Objective-J/Tools/steam/steam.xml b/Objective-J/Tools/steam/steam.xml
new file mode 100644
index 000000000..8b5e0a9f6
--- /dev/null
+++ b/Objective-J/Tools/steam/steam.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Objective-J/Tools/steam/usage.js b/Objective-J/Tools/steam/usage.js
new file mode 100644
index 000000000..389fadc53
--- /dev/null
+++ b/Objective-J/Tools/steam/usage.js
@@ -0,0 +1,22 @@
+function printUsage(command)
+{
+ var usage = "usage: steam COMMAND [ARGS]\n\n"+
+"The most commonly used steam commands are:\n"+
+"\tbuild Build a project\n"+
+"\tcreate Create a new project\n\n"+
+"See 'steam help COMMAND' for more information on a specific command.";
+
+ switch (command)
+ {
+ case "--help":
+ case undefined: java.lang.System.out.println(usage);
+ break;
+
+ case "create": java.lang.System.out.println("Creates a new Cappuccino project.\n\nusage: steam create PROJECT_NAME [-l]\n\n"+
+ "\t-l Link Frameworks to $STEAM_BUILD/Release, instead of installing default Frameworks");
+ break;
+
+ default: java.lang.System.out.println("steam: '" + command + "' is not a steam command. See 'steam --help'.");
+ }
+ java.lang.System.exit(1);
+}
diff --git a/Objective-J/Tools/steam/version.js b/Objective-J/Tools/steam/version.js
new file mode 100644
index 000000000..c22171a3f
--- /dev/null
+++ b/Objective-J/Tools/steam/version.js
@@ -0,0 +1,5 @@
+function printVersion()
+{
+ java.lang.System.out.println("steam version 0.6");
+ java.lang.System.exit(1);
+}
\ No newline at end of file
diff --git a/Objective-J/build.xml b/Objective-J/build.xml
index 2c378ae2b..9e1a1bd0f 100644
--- a/Objective-J/build.xml
+++ b/Objective-J/build.xml
@@ -1,64 +1,27 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Objective-J/rakefile b/Objective-J/rakefile
new file mode 100644
index 000000000..4631e50dd
--- /dev/null
+++ b/Objective-J/rakefile
@@ -0,0 +1,13 @@
+#!/usr/bin/env ruby
+
+require 'rake'
+require '../common'
+
+
+subprojects = %w{Runtime Tools}
+
+%w(build clean).each do |task_name|
+ task task_name do
+ subrake(subprojects)
+ end
+end
diff --git a/Rake/LGPL-v2.1 b/Rake/LGPL-v2.1
new file mode 100644
index 000000000..9ef3d701d
--- /dev/null
+++ b/Rake/LGPL-v2.1
@@ -0,0 +1,503 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
diff --git a/Rake/Resources/objj-exec b/Rake/Resources/objj-exec
new file mode 100644
index 000000000..f2d87c461
--- /dev/null
+++ b/Rake/Resources/objj-exec
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+# if OBJJ_HOME isn't set, try to determine it out
+if [ -z $OBJJ_HOME ]; then
+ # get path of the executable
+ SELF_PATH=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && SELF_PATH=$SELF_PATH/$(basename -- "$0")
+
+ # resolve symlinks
+ if [ -h $SELF_PATH ]; then
+ SELF_PATH=`readlink $SELF_PATH`
+ fi
+
+ # get second ancestor directory
+ SELF_DIR=`dirname $SELF_PATH`
+ export OBJJ_HOME=`dirname $SELF_DIR`
+
+ # check to ensure it exists, print message
+ if [ -d $OBJJ_HOME ]; then
+ echo "OBJJ_HOME not set, defaulting to $OBJJ_HOME" 1>&2
+ else
+ echo "OBJJ_HOME not set, default at $OBJJ_HOME doesn't exist, exiting" 1>&2
+ exit 2
+ fi
+fi
+
+OBJJ_LIB="$OBJJ_HOME/lib"
+CLASSPATH="$OBJJ_LIB:$OBJJ_LIB/js.jar:$OBJJ_HOME/lib/$(basename $SELF_PATH):$CLASSPATH"
+
+OBJJ="$OBJJ_LIB/objj.js"
+RLWRAP=`which rlwrap`
+
+# if there's a "lib" directory, add all the jars from it
+if [ -d "lib" ]; then
+ JARS=`find ./lib -name '*.jar' 2> /dev/null | tr "\n" ":"`
+ CLASSPATH="$JARS:$CLASSPATH"
+fi
+
+# convert paths for Cygwin
+if [[ `uname` == CYGWIN* ]]; then
+ OBJJ_HOME=`cygpath -wp "$OBJJ_HOME"`
+ OBJJ_LIB=`cygpath -wp "$OBJJ_LIB"`
+ OBJJ=`cygpath -wp "$OBJJ"`
+ CLASSPATH=`cygpath -wp "$CLASSPATH"`
+fi
+
+export OBJJ_LIB
+echo $RLWRAP java -classpath $CLASSPATH main $@
+#if [ -e $STEAM_BUILD/Objective-J.build/Release/Rhino ]; then
+ $RLWRAP java -classpath $CLASSPATH main $@
+ #$RLWRAP java -classpath $CLASSPATH org.mozilla.javascript.tools.shell.Main $OBJJ $@
+#else
+# echo "Missing frameworks at $STEAM_BUILD/Objective-J.build/Release/Rhino" 1>&2
+#fi
diff --git a/Rake/objective-j.rb b/Rake/objective-j.rb
new file mode 100644
index 000000000..7d41aa4b6
--- /dev/null
+++ b/Rake/objective-j.rb
@@ -0,0 +1,524 @@
+require 'rake'
+require 'date'
+
+module ObjectiveJ
+
+ class Platform
+ OBJJ = 'objj'
+ RHINO = 'rhino'
+ BROWSER = 'browser'
+ end
+
+ ##
+ # == ObjectiveJ::BundleSpecification
+ #
+ # The Specification class contains the metadata for a Framework. Typically defined in a
+ # Rakefile, and looks like this:
+ #
+ # spec = ObjJ::BundleSpecification.new do |s|
+ # s.name = 'NewKit'
+ # s.version = '1.0'
+ # s.summary = 'Example framework specification'
+ # ...
+ # end
+ #
+ # There are many framework attributes, and the best place to learn about them in
+ # the "Framework Reference" linked from the Cappuccino wiki.
+ #
+
+ class BundleSpecification
+
+ # ------------------------- Specification version contstants.
+
+ # The specification version applied to any new Specification instances created. This
+ # should be bumped whenever something in the spec format changes.
+ CURRENT_SPECIFICATION_VERSION = 1
+
+ # An informal list of changes to the specification. The highest-valued key should be
+ # equal to the CURRENT_SPECIFICATION_VERSION.
+ SPECIFICATION_VERSION_HISTORY = {
+ -1 => ['(RubyGems versions up to and including 0.7 did not have versioned specifications)'],
+ 1 => [
+ 'First Specification'
+ ]
+ }
+
+ # ------------------------- Class variables.
+
+ # List of Specification instances.
+ @@list = []
+
+ # Optional block used to gather newly defined instances.
+ @@gather = nil
+
+ # List of attribute names: [:name, :version, ...]
+ @@required_attributes = []
+
+ # List of _all_ attributes and default values: [[:name, nil], [:bindir, 'bin'], ...]
+ @@attributes = []
+
+ # List of array attributes
+ @@array_attributes = []
+
+ # Map of attribute names to default values.
+ @@default_value = {}
+
+ # ------------------------- Convenience class methods.
+
+ def self.attribute_names
+ @@attributes.map { |name, default| name }
+ end
+
+ def self.attribute_defaults
+ @@attributes.dup
+ end
+
+ def self.default_value(name)
+ @@default_value[name]
+ end
+
+ def self.required_attributes
+ @@required_attributes.dup
+ end
+
+ def self.required_attribute?(name)
+ @@required_attributes.include? name.to_sym
+ end
+
+ def self.array_attributes
+ @@array_attributes.dup
+ end
+
+ # ------------------------- Infrastructure class methods.
+
+ # A list of Specification instances that have been defined in this Ruby instance.
+ def self.list
+ @@list
+ end
+
+ ##
+ # Used to specify the name and default value of a specification attribute. The side
+ # effects are:
+ # * the name and default value are added to the @@attributes list and
+ # @@default_value map
+ # * a standard _writer_ method (attribute=) is created
+ # * a non-standard _reader method (attribute) is created
+ #
+ # The reader method behaves like this:
+ # def attribute
+ # @attribute ||= (copy of default value)
+ # end
+ #
+ # This allows lazy initialization of attributes to their default values.
+ #
+ def self.attribute(name, default=nil)
+ @@attributes << [name, default]
+ @@default_value[name] = default
+ attr_accessor(name)
+ end
+
+ # Same as :attribute, but ensures that values assigned to the
+ # attribute are array values by applying :to_a to the value.
+ def self.array_attribute(name)
+ @@array_attributes << name
+ @@attributes << [name, []]
+ @@default_value[name] = []
+ module_eval %{
+ def #{name}
+ @#{name} ||= []
+ end
+ def #{name}=(value)
+ @#{name} = value.to_a
+ end
+ }
+ end
+
+ # Same as attribute above, but also records this attribute as mandatory.
+ def self.required_attribute(*args)
+ @@required_attributes << args.first
+ attribute(*args)
+ end
+
+ # Sometimes we don't want the world to use a setter method for a particular attribute.
+ # +read_only+ makes it private so we can still use it internally.
+ def self.read_only(*names)
+ names.each do |name|
+ private "#{name}="
+ end
+ end
+
+ # Shortcut for creating several attributes at once (each with a default value of
+ # +nil+).
+ def self.attributes(*args)
+ args.each do |arg|
+ attribute(arg, nil)
+ end
+ end
+
+ # Some attributes require special behaviour when they are accessed. This allows for
+ # that.
+ def self.overwrite_accessor(name, &block)
+ remove_method name
+ define_method(name, &block)
+ end
+
+ ##
+ # Defines a _singular_ version of an existing _plural_ attribute (i.e. one whose value
+ # is expected to be an array). This means just creating a helper method that takes a
+ # single value and appends it to the array. These are created for convenience, so
+ # that in a spec, one can write
+ #
+ # s.require_path = 'mylib'
+ #
+ # instead of
+ #
+ # s.require_paths = ['mylib']
+ #
+ # That above convenience is available courtesy of
+ #
+ # attribute_alias_singular :require_path, :require_paths
+ #
+ def self.attribute_alias_singular(singular, plural)
+ define_method("#{singular}=") { |val|
+ send("#{plural}=", [val])
+ }
+ define_method("#{singular}") {
+ val = send("#{plural}")
+ val.nil? ? nil : val.first
+ }
+ end
+
+ # ------------------------- REQUIRED framework attributes.
+
+ required_attribute :specification_version, CURRENT_SPECIFICATION_VERSION
+ required_attribute :name
+ required_attribute :version
+ #required_attribute :date
+ attribute :date
+ required_attribute :summary
+ required_attribute :identifier
+
+ read_only :specification_version
+
+ # ------------------------- OPTIONAL gemspec attributes.
+
+ attributes :email, :homepage, :github_project, :description, :license_file, :license
+ attributes :build_path, :intermediates_path
+ # attributes :autorequire, :default_executable
+ # attribute :platform, Gem::Platform::RUBY
+
+ array_attribute :authors
+ array_attribute :sources
+ array_attribute :resources
+ array_attribute :flags
+ # array_attribute :test_files
+ # array_attribute :executables
+ # array_attribute :extensions
+ # array_attribute :requirements
+ # array_attribute :dependencies
+
+ #read_only :dependencies
+
+ # ------------------------- ALIASED gemspec attributes.
+
+ # attribute_alias_singular :executable, :executables
+ attribute_alias_singular :author, :authors
+ attribute_alias_singular :flag, :flags
+ # attribute_alias_singular :require_path, :require_paths
+ # attribute_alias_singular :test_file, :test_files
+
+ # ------------------------- RUNTIME attributes (not persisted).
+
+ attr_writer :loaded
+ attr_accessor :loaded_from
+
+ # ------------------------- Special accessor behaviours (overwriting default).
+
+# overwrite_accessor :version= do |version|
+# @version = Version.create(version)
+# end
+
+ overwrite_accessor :date= do |date|
+ # We want to end up with a Time object with one-day resolution. This is
+ # the cleanest, most-readable, faster-than-using-Date way to do it.
+ case date
+ when String then
+ @date = Time.parse date
+ when Time then
+ @date = Time.parse date.strftime("%Y-%m-%d")
+ when Date then
+ @date = Time.parse date.to_s
+ else
+ @date = Time.today
+ end
+ end
+
+ overwrite_accessor :date do
+ self.date = nil if @date.nil? # HACK Sets the default value for date
+ @date
+ end
+
+ overwrite_accessor :summary= do |str|
+ if str
+ @summary = str.strip.gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ")
+ end
+ end
+
+ overwrite_accessor :description= do |str|
+ if str
+ @description = str.strip.gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ")
+ end
+ end
+
+ def files
+ (@sources || []) | (@resources || []) | (@license_file ? [@license_file] : [])
+ end
+
+ overwrite_accessor :intermediates_path do
+ return @intermediates_path || name + '.build'
+ end
+
+ overwrite_accessor :build_path do
+ return @build_path || './' + name
+ end
+=begin
+ overwrite_accessor :test_files do
+ # Handle the possibility that we have @test_suite_file but not @test_files. This will
+ # happen when an old gem is loaded via YAML.
+ if @test_suite_file
+ @test_files = [@test_suite_file].flatten
+ @test_suite_file = nil
+ end
+ @test_files ||= []
+ end
+=end
+
+ # ------------------------- Predicates.
+
+ def loaded?; @loaded ? true : false ; end
+ # def has_unit_tests?; not test_files.empty?; end
+
+ # ------------------------- Constructors.
+
+ ##
+ # Specification constructor. Assigns the default values to the
+ # attributes, adds this spec to the list of loaded specs (see
+ # Specification.list), and yields itself for further initialization.
+ #
+ def initialize
+ # Each attribute has a default value (possibly nil). Here, we
+ # initialize all attributes to their default value. This is done
+ # through the accessor methods, so special behaviours will be honored.
+ # Furthermore, we take a _copy_ of the default so each specification
+ # instance has its own empty
+ # arrays, etc.
+ @@attributes.each do |name, default|
+ self.send "#{name}=", copy_of(default)
+ end
+ @loaded = false
+ @@list << self
+ yield self if block_given?
+ @@gather.call(self) if @@gather
+ end
+=begin
+ ##
+ # Special loader for YAML files. When a Specification object is loaded from a YAML file,
+ # it bypasses the normal Ruby object initialization routine (#initialize). This method
+ # makes up for that and deals with gems of different ages.
+ #
+ # 'input' can be anything that YAML.load() accepts: String or IO.
+ #
+ def Specification.from_yaml(input)
+ spec = YAML.load(input)
+ if(spec.class == FalseClass) then
+ raise Gem::EndOfYAMLException
+ end
+ unless Specification === spec
+ raise Gem::Exception, "YAML data doesn't evaluate to gem specification"
+ end
+ unless spec.instance_variable_get :@specification_version
+ spec.instance_variable_set :@specification_version, NONEXISTENT_SPECIFICATION_VERSION
+ end
+ spec
+ end
+=end
+
+ def BundleSpecification.load(filename)
+ gemspec = nil
+ fail "NESTED Specification.load calls not allowed!" if @@gather
+ @@gather = proc { |gs| gemspec = gs }
+ data = File.read(filename)
+ eval(data)
+ gemspec
+ ensure
+ @@gather = nil
+ end
+
+ # ------------------------- Instance methods.
+
+ ##
+ # Returns the full name (name-version) of this Framework.
+ #
+ def full_name
+ @name
+ end
+
+ # ------------------------- Comparison methods.
+
+ ##
+ # Compare specs (name then version).
+ #
+ def <=>(other)
+ [@name, @version] <=> [other.name, other.version]
+ end
+
+ # Tests specs for equality (across all attributes).
+ def ==(other)
+ @@attributes.each do |name, default|
+ return false unless self.send(name) == other.send(name)
+ end
+ true
+ end
+=begin
+ # ------------------------- Export methods (YAML and Ruby code).
+
+ # Returns an array of attribute names to be used when generating a YAML
+ # representation of this object. If an attribute still has its default
+ # value, it is omitted.
+ def to_yaml_properties
+ mark_version
+ @@attributes.map { |name, default| "@#{name}" }
+ end
+
+ # Returns a Ruby code representation of this specification, such that it
+ # can be eval'ed and reconstruct the same specification later. Attributes
+ # that still have their default values are omitted.
+ def to_ruby
+ mark_version
+ result = "Gem::Specification.new do |s|\n"
+ @@attributes.each do |name, default|
+ # TODO better implementation of next line (read_only_attribute? ... something like that)
+ next if name == :dependencies or name == :specification_version
+ current_value = self.send(name)
+ result << " s.#{name} = #{ruby_code(current_value)}\n" unless current_value == default
+ end
+ dependencies.each do |dep|
+ version_reqs_param = dep.requirements_list.inspect
+ result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})\n"
+ end
+ result << "end\n"
+ end
+=end
+ # ------------------------- Validation and normalization methods.
+
+ ##
+ # Checks that the specification contains all required fields, and
+ # does a very basic sanity check.
+ #
+ # Raises InvalidSpecificationException if the spec does not pass
+ # the checks..
+ def validate
+=begin
+ normalize
+ if rubygems_version != RubyGemsVersion
+ raise InvalidSpecificationException.new(%[
+ Expected RubyGems Version #{RubyGemsVersion}, was #{rubygems_version}
+ ].strip)
+ end
+=end
+ @@required_attributes.each do |symbol|
+ unless self.send(symbol)
+ raise InvalidSpecificationException.new("Missing value for attribute #{symbol}")
+ end
+ end
+=begin
+ if require_paths.empty?
+ raise InvalidSpecificationException.new("Framework spec needs to have at least one require_path")
+ end
+=end
+ end
+
+ ##
+ # Normalize the list of files so that:
+ # * All file lists have redundancies removed.
+ # * Files referenced in the extra_rdoc_files are included in the package file list.
+ #
+ # Also, the summary and description are converted to a normal format.
+ def normalize
+=begin
+ if @extra_rdoc_files
+ @extra_rdoc_files.uniq!
+ @files ||= []
+ @files.concat(@extra_rdoc_files)
+ end
+=end
+ @files.uniq! if @files
+ end
+
+ def to_s
+ "#"
+ end
+
+ def info_plist
+ return { 'CPBundleName' => name, 'CPBundleIdentifier' => identifier, 'CPBundleInfoDictionaryVersion' => 6.0, 'CPBundleVersion' => version }
+ end
+
+ private
+=begin
+ def find_all_satisfiers(dep)
+ Gem.source_index.each do |name,gem|
+ if(gem.satisfies_requirement?(dep)) then
+ yield gem
+ end
+ end
+ end
+=end
+ # Duplicate an object unless it's an immediate value.
+ def copy_of(obj)
+ case obj
+ when Numeric, Symbol, true, false, nil then obj
+ else obj.dup
+ end
+ end
+
+ # Return a string containing a Ruby code representation of the given object.
+ def ruby_code(obj)
+ case obj
+ when String then '%q{' + obj + '}'
+ when Array then obj.inspect
+ when Gem::Version then obj.to_s.inspect
+ when Date, Time then '%q{' + obj.strftime('%Y-%m-%d') + '}'
+ when Numeric then obj.inspect
+ when true, false, nil then obj.inspect
+ when Gem::Version::Requirement then "Gem::Version::Requirement.new(#{obj.to_s.inspect})"
+ else raise Exception, "ruby_code case not handled: #{obj.class}"
+ end
+ end
+
+ end # class BundleSpecification
+
+end # module ObjectiveJ
+
+module ObjectiveJ
+
+ module License
+ LGPL_v2_1 = 'LGPL_v2_1'
+ end
+
+end
+
+def file_d(*args, &block)
+
+ fileTask = file_create(*args, &block)
+
+ fileDirectory = File.dirname(fileTask.name)
+ directory fileDirectory
+
+ file fileTask.name => fileDirectory
+
+end
+
+def bundle(spec, *args, &block)
+ task = ObjectiveJ::BundleTask.define_task(*args, &block)
+ task.bundle_spec = spec
+end
diff --git a/Rake/objective-j/bundle.rb b/Rake/objective-j/bundle.rb
new file mode 100644
index 000000000..fb0ced840
--- /dev/null
+++ b/Rake/objective-j/bundle.rb
@@ -0,0 +1,146 @@
+require 'rake'
+require 'objective-j/plist'
+
+module ObjectiveJ
+
+ # Create a package based upon a Gem spec. Gem packages, as well as
+ # zip files and tar/gzipped packages can be produced by this task.
+ #
+ # In addition to the Rake targets generated by PackageTask, a
+ # GemPackageTask will also generate the following tasks:
+ #
+ # ["package_dir/name-version.gem"]
+ # Create a Ruby GEM package with the given name and version.
+ #
+ # Example using a Ruby GEM spec:
+ #
+ # require 'rubygems'
+ #
+ # spec = Gem::Specification.new do |s|
+ # s.platform = Gem::Platform::RUBY
+ # s.summary = "Ruby based make-like utility."
+ # s.name = 'rake'
+ # s.version = PKG_VERSION
+ # s.requirements << 'none'
+ # s.require_path = 'lib'
+ # s.autorequire = 'rake'
+ # s.files = PKG_FILES
+ # s.description = < [resource] do
+ cp_r(resource, resources_path)
+ end
+
+ copied_resources << copied_resource
+ end
+
+ objects_path = @bundle_spec.intermediates_path
+ objects = []
+ replaced_files = []
+
+ # create file tasks for object files
+ @bundle_spec.sources.each do |source|
+
+ object_path = File.join(objects_path, File.basename(source, File.extname(source))) + '.o'
+ flags = []
+
+ @bundle_spec.flags.each do |flag|
+ flags << '-D' + flag
+ end
+
+ file_d object_path => source do
+ IO.popen("objjc #{flags.join(' ')} #{source} -o #{object_path}") do |objjc|
+ puts objjc.read
+ end
+ end
+
+ objects << object_path
+ replaced_files << File.basename(source)
+ end
+
+ #the actual executable path
+ executable_path = File.join(@bundle_spec.build_path, @bundle_spec.name + '.sj')
+
+ # copy license file
+ license_path = nil
+
+ # check if a license type has been specified
+ if @bundle_spec.license != nil
+
+ copied_license = @bundle_spec.build_path + '/LICENSE'
+
+ case @bundle_spec.license
+ when License::LGPL_v2_1
+ license_path = File.expand_path(File.join(File.dirname(__FILE__), '../LGPL-v2.1'))
+ else
+ license_path = license
+ end
+
+ file_d executable_path => copied_license
+
+ file_d copied_license => license_path do
+ cp(license_path, copied_license)
+ end
+ end
+
+ file executable_path => objects do
+
+ File.open(executable_path, "w") do |file|
+
+ file.write('@STATIC;1.0;')
+
+ objects.each do |object|
+ file.write(IO.read(object))
+ end
+ end
+ end
+
+ info_plist_path = @bundle_spec.build_path + '/Info.plist'
+ info_plist = @bundle_spec.info_plist
+
+ info_plist['CPBundleExecutable'] = File.basename(executable_path)
+ info_plist['CPBundleReplacedFiles'] = replaced_files
+
+ file_d info_plist_path do
+ File.open(info_plist_path, 'w') do |file|
+ file.puts info_plist.to_plist
+ end
+ end
+
+ enhance(copied_resources + [executable_path, info_plist_path])
+ end
+ end
+end
diff --git a/Rake/objective-j/plist.rb b/Rake/objective-j/plist.rb
new file mode 100644
index 000000000..d993be27a
--- /dev/null
+++ b/Rake/objective-j/plist.rb
@@ -0,0 +1,134 @@
+require 'rake'
+
+module ObjectiveJ
+ PLIST_START = '
+
+'
+ PLIST_END = ''
+end
+
+class Module
+
+ def objj_extension(method)
+
+ if instance_methods.include?(method)
+ $stderr.puts "WARNING: Possible conflict with Objective-J extension: #{self}##{method} already exists"
+ else
+ yield
+ end
+ end
+
+end
+
+class Array
+
+ objj_extension('to_plist') do
+ def to_plist(start = true)
+
+ str = ''
+
+ each do |value|
+ str += value.to_plist(false)
+ end
+
+ str = str + ''
+ str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
+
+ return str
+ end
+ end
+end
+
+class FalseClass
+
+ objj_extension('to_plist') do
+ def to_plist(start = true)
+
+ str = ''
+ str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
+
+ return str
+ end
+ end
+end
+
+class Float
+
+ objj_extension('to_plist') do
+ def to_plist(start = true)
+
+ str = '' + to_s + ''
+ str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
+
+ return str
+ end
+ end
+end
+
+class Hash
+
+ objj_extension('to_plist') do
+ def to_plist(start = true)
+
+ str = ''
+
+ each do |key, value|
+ str += '' + key.html_encode + '' + value.to_plist(false)
+ end
+
+ str += ''
+ str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
+
+ return str
+ end
+ end
+end
+
+class Integer
+
+ objj_extension('to_plist') do
+ def to_plist(start = true)
+
+ str = '' + to_s + ''
+ str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END
+
+ return str
+ end
+ end
+end
+
+class String
+
+ objj_extension('to_plist') do
+ def to_plist(start = true)
+
+ str = '' + html_encode + ''
+ str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
+
+ return str
+ end
+ end
+
+ objj_extension('html_encode') do
+ def html_encode
+ return self.gsub(/, '<').
+ gsub(/>/, '>').
+ gsub(/"/,'"').
+ gsub(/'/, ''').
+ gsub(/&/, '&')
+ end
+ end
+end
+
+class TrueClass
+
+ objj_extension('to_plist') do
+ def to_plist(start = true)
+
+ str = ''
+ str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
+
+ return str
+ end
+ end
+end
diff --git a/Tools/objj/build.xml b/Tools/objj/build.xml
deleted file mode 100644
index c8d58a585..000000000
--- a/Tools/objj/build.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Tools/objjc/build.xml b/Tools/objjc/build.xml
deleted file mode 100644
index c3fbd2f27..000000000
--- a/Tools/objjc/build.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/common.rb b/common.rb
new file mode 100644
index 000000000..7cba7ef64
--- /dev/null
+++ b/common.rb
@@ -0,0 +1,83 @@
+require 'rake'
+
+# Read in and set up development environment variables.
+if !ENV['BUILD_DIR']
+
+ # Global Cappuccino build directory
+ if ENV['CAPP_BUILD']
+ ENV['BUILD_DIR'] = ENV['CAPP_BUILD']
+
+ # Maintain backwards compatibility with steam.
+ elsif ENV['STEAM_BUILD']
+ ENV['BUILD_DIR'] = ENV['STEAM_BUILD']
+
+ # Just build here.
+ else
+ ENV['BUILD_DIR'] = File.join(File.dirname(__FILE__), 'Build')
+ end
+end
+
+if !ENV['CONFIG']
+ ENV['CONFIG'] = 'Release'
+end
+
+$CONFIGURATION = ENV['CONFIG']
+$BUILD_DIR = File.expand_path(ENV['BUILD_DIR'])
+$PRODUCT_DIR = File.join($BUILD_DIR, $CONFIGURATION)
+$ENVIRONMENT_DIR = File.join($BUILD_DIR, $CONFIGURATION, 'env')
+$ENVIRONMENT_BIN_DIR = File.join($ENVIRONMENT_DIR, 'bin')
+$ENVIRONMENT_LIB_DIR = File.join($ENVIRONMENT_DIR, 'lib')
+$ENVIRONMENT_FRAMEWORKS_DIR = File.join($ENVIRONMENT_LIB_DIR, 'Frameworks')
+
+$HOME_DIR = File.expand_path(File.dirname(__FILE__))
+$LICENSE_FILE = File.expand_path(File.join(File.dirname(__FILE__), 'LICENSE'))
+
+if !(defined? COMMON_DO_ONCE)
+
+ COMMON_DO_ONCE = true
+
+ $LOAD_PATH << File.join($HOME_DIR, 'Rake')
+ ENV['PATH'] = $ENVIRONMENT_BIN_DIR + ':' + ENV['PATH']
+end
+
+require 'objective-j'
+
+$env = ""
+$env += %{CONFIG="#{ENV['CONFIG']}" } if ENV['CONFIG']
+$env += %{BUILD_DIR="#{ENV['BUILD_DIR']}" } if ENV['BUILD_DIR']
+
+def subrake(directories)
+ directories.each do |directory|
+ system %{cd #{directory} && #{$env} #{$0}}
+ end
+end
+
+# Shared Resrouces in env
+$JSJAR_PATH = File.expand_path(File.join($HOME_DIR, 'Tools/Utilities/js.jar'))
+$ENVIRONMENT_JS = File.join($ENVIRONMENT_LIB_DIR, 'js.jar')
+
+file_d $ENVIRONMENT_JS do
+ cp($JSJAR_PATH, $ENVIRONMENT_JS)
+end
+
+def js2java(inputfile, className, debug)
+
+ debugString = '-nosource -debug' if debug
+
+ IO.popen("java -classpath #{$JSJAR_PATH}:. #{debugString} org.mozilla.javascript.tools.jsc.Main -o #{className} #{inputfile}") do |shrinksafe|
+ puts shrinksafe.read
+ end
+end
+
+def cat(files, outfile)
+
+ File.open(outfile, "w") do |concated|
+
+ files.each do |file|
+ concated.write IO.read(file)
+ end
+ end
+end
+
+task :build => [$ENVIRONMENT_JS]
+task :default => [:build]
diff --git a/rakefile b/rakefile
new file mode 100644
index 000000000..253d35f74
--- /dev/null
+++ b/rakefile
@@ -0,0 +1,15 @@
+#!/usr/bin/env ruby
+
+require 'rake'
+require 'common'
+
+
+subprojects = %w{Objective-J Foundation AppKit}
+
+%w(build clean).each do |task_name|
+ task task_name do
+ subrake(subprojects)
+ end
+end
+
+#task :deploy => [:build]
\ No newline at end of file