Revision: 1542
          http://rigsofrods.svn.sourceforge.net/rigsofrods/?rev=1542&view=rev
Author:   rorthomas
Date:     2010-12-11 11:40:06 +0000 (Sat, 11 Dec 2010)

Log Message:
-----------
updates for angelscript 2.20.1

Modified Paths:
--------------
    trunk/source/main/angelscript/scripthelper/scripthelper.cpp
    trunk/source/main/angelscript/scripthelper/scripthelper.h
    trunk/source/main/angelscript/scriptmath/scriptmath.cpp
    trunk/source/main/angelscript/scriptmath3d/scriptmath3d.cpp
    trunk/source/main/angelscript/scriptstdstring/scriptstdstring.cpp
    trunk/source/main/angelscript/scriptstdstring/scriptstdstring.h

Modified: trunk/source/main/angelscript/scripthelper/scripthelper.cpp
===================================================================
--- trunk/source/main/angelscript/scripthelper/scripthelper.cpp 2010-10-06 
16:06:18 UTC (rev 1541)
+++ trunk/source/main/angelscript/scripthelper/scripthelper.cpp 2010-12-11 
11:40:06 UTC (rev 1542)
@@ -1,8 +1,8 @@
-#ifdef USE_ANGELSCRIPT
-
 #include <string.h>
 #include "scripthelper.h"
 #include <string>
+#include <assert.h>
+#include <stdio.h>
 
 using namespace std;
 
@@ -160,6 +160,187 @@
        return r;
 }
 
+int WriteConfigToFile(asIScriptEngine *engine, const char *filename)
+{
+       int c, n;
+
+       FILE *f = 0;
+#if _MSC_VER >= 1400 // MSVC 8.0 / 2005
+       fopen_s(&f, filename, "wt");
+#else
+       f = fopen(filename, "wt");
+#endif
+       if( f == 0 )
+               return -1;
+
+       // Make sure the default array type is expanded to the template form 
+       bool expandDefArrayToTempl = 
engine->GetEngineProperty(asEP_EXPAND_DEF_ARRAY_TO_TMPL) ? true : false;
+       engine->SetEngineProperty(asEP_EXPAND_DEF_ARRAY_TO_TMPL, true);
+
+       // Write enum types and their values
+       fprintf(f, "// Enums\n");
+       c = engine->GetEnumCount();
+       for( n = 0; n < c; n++ )
+       {
+               int typeId;
+               const char *enumName = engine->GetEnumByIndex(n, &typeId);
+               fprintf(f, "enum %s\n", enumName);
+               for( int m = 0; m < engine->GetEnumValueCount(typeId); m++ )
+               {
+                       const char *valName;
+                       int val;
+                       valName = engine->GetEnumValueByIndex(typeId, m, &val);
+                       fprintf(f, "enumval %s %s %d\n", enumName, valName, 
val);
+               }
+       }
+
+       // Enumerate all types
+       fprintf(f, "\n// Types\n");
+
+       c = engine->GetObjectTypeCount();
+       for( n = 0; n < c; n++ )
+       {
+               asIObjectType *type = engine->GetObjectTypeByIndex(n);
+               if( type->GetFlags() & asOBJ_SCRIPT_OBJECT )
+               {
+                       // This should only be interfaces
+                       assert( type->GetSize() == 0 );
+
+                       fprintf(f, "intf %s\n", type->GetName());
+               }
+               else
+               {
+                       // Only the type flags are necessary. The application 
flags are application 
+                       // specific and doesn't matter to the offline compiler. 
The object size is also
+                       // unnecessary for the offline compiler
+                       fprintf(f, "objtype \"%s\" %u\n", 
engine->GetTypeDeclaration(type->GetTypeId()), (unsigned int)(type->GetFlags() 
& 0xFF));
+               }
+       }
+
+       c = engine->GetTypedefCount();
+       for( n = 0; n < c; n++ )
+       {
+               int typeId;
+               const char *typeDef = engine->GetTypedefByIndex(n, &typeId);
+               fprintf(f, "typedef %s \"%s\"\n", typeDef, 
engine->GetTypeDeclaration(typeId));
+       }
+
+       c = engine->GetFuncdefCount();
+       for( n = 0; n < c; n++ )
+       {
+               asIScriptFunction *funcDef = engine->GetFuncdefByIndex(n);
+               fprintf(f, "funcdef \"%s\"\n", funcDef->GetDeclaration());
+       }
+
+       // Write the object types members
+       fprintf(f, "\n// Type members\n");
+       
+       c = engine->GetObjectTypeCount();
+       for( n = 0; n < c; n++ )
+       {
+               asIObjectType *type = engine->GetObjectTypeByIndex(n);
+               string typeDecl = engine->GetTypeDeclaration(type->GetTypeId());
+               if( type->GetFlags() & asOBJ_SCRIPT_OBJECT )
+               {
+                       for( int m = 0; m < type->GetMethodCount(); m++ )
+                       {
+                               asIScriptFunction *func = 
type->GetMethodDescriptorByIndex(m);
+                               fprintf(f, "intfmthd %s \"%s\"\n", 
typeDecl.c_str(), func->GetDeclaration(false));
+                       }
+               }
+               else
+               {
+                       int m;
+                       for( m = 0; m < type->GetFactoryCount(); m++ )
+                       {
+                               asIScriptFunction *func = 
engine->GetFunctionDescriptorById(type->GetFactoryIdByIndex(m));
+                               fprintf(f, "objbeh \"%s\" %d \"%s\"\n", 
typeDecl.c_str(), asBEHAVE_FACTORY, func->GetDeclaration(false));
+                       }
+                       for( m = 0; m < type->GetBehaviourCount(); m++ )
+                       {
+                               asEBehaviours beh;
+                               asIScriptFunction *func = 
engine->GetFunctionDescriptorById(type->GetBehaviourByIndex(m, &beh));
+                               fprintf(f, "objbeh \"%s\" %d \"%s\"\n", 
typeDecl.c_str(), beh, func->GetDeclaration(false));
+                       }
+                       for( m = 0; m < type->GetMethodCount(); m++ )
+                       {
+                               asIScriptFunction *func = 
type->GetMethodDescriptorByIndex(m);
+                               fprintf(f, "objmthd \"%s\" \"%s\"\n", 
typeDecl.c_str(), func->GetDeclaration(false));
+                       }
+                       for( m = 0; m < type->GetPropertyCount(); m++ )
+                       {
+                               fprintf(f, "objprop \"%s\" \"%s\"\n", 
typeDecl.c_str(), type->GetPropertyDeclaration(m));
+                       }
+               }
+       }
+
+       // Write functions
+       fprintf(f, "\n// Functions\n");
+
+       c = engine->GetGlobalFunctionCount();
+       for( n = 0; n < c; n++ )
+       {
+               asIScriptFunction *func = 
engine->GetFunctionDescriptorById(engine->GetGlobalFunctionIdByIndex(n));
+               fprintf(f, "func \"%s\"\n", func->GetDeclaration());
+       }
+
+       // Write global properties
+       fprintf(f, "\n// Properties\n");
+
+       c = engine->GetGlobalPropertyCount();
+       for( n = 0; n < c; n++ )
+       {
+               const char *name;
+               int typeId;
+               bool isConst;
+               engine->GetGlobalPropertyByIndex(n, &name, &typeId, &isConst); 
+               fprintf(f, "prop \"%s%s %s\"\n", isConst ? "const " : "", 
engine->GetTypeDeclaration(typeId), name);
+       }
+
+       // Write string factory
+       fprintf(f, "\n// String factory\n");
+       int typeId = engine->GetStringFactoryReturnTypeId();
+       if( typeId > 0 )
+               fprintf(f, "strfactory \"%s\"\n", 
engine->GetTypeDeclaration(typeId));
+
+       // Write default array type
+       fprintf(f, "\n// Default array type\n");
+       typeId = engine->GetDefaultArrayTypeId();
+       if( typeId > 0 )
+               fprintf(f, "defarray \"%s\"\n", 
engine->GetTypeDeclaration(typeId));
+
+       fclose(f);
+
+       // Restore original settings
+       engine->SetEngineProperty(asEP_EXPAND_DEF_ARRAY_TO_TMPL, 
expandDefArrayToTempl);
+
+       return 0;
+}
+
+void PrintException(asIScriptContext *ctx, bool printStack)
+{
+       if( ctx->GetState() != asEXECUTION_EXCEPTION ) return;
+
+       asIScriptEngine *engine = ctx->GetEngine();
+       int funcId = ctx->GetExceptionFunction();
+       const asIScriptFunction *function = 
engine->GetFunctionDescriptorById(funcId);
+       printf("func: %s\n", function->GetDeclaration());
+       printf("modl: %s\n", function->GetModuleName());
+       printf("sect: %s\n", function->GetScriptSectionName());
+       printf("line: %d\n", ctx->GetExceptionLineNumber());
+       printf("desc: %s\n", ctx->GetExceptionString());
+
+       if( printStack )
+       {
+               printf("--- call stack ---\n");
+               for( asUINT n = 1; n < ctx->GetCallstackSize(); n++ )
+               {
+                       function = ctx->GetFunction(n);
+                       printf("%s (%d): %s\n", 
function->GetScriptSectionName(),
+                                               ctx->GetLineNumber(n),
+                                                                   
function->GetDeclaration());
+               }
+       }
+}
+
 END_AS_NAMESPACE
-
-#endif //USE_ANGELSCRIPT

Modified: trunk/source/main/angelscript/scripthelper/scripthelper.h
===================================================================
--- trunk/source/main/angelscript/scripthelper/scripthelper.h   2010-10-06 
16:06:18 UTC (rev 1541)
+++ trunk/source/main/angelscript/scripthelper/scripthelper.h   2010-12-11 
11:40:06 UTC (rev 1542)
@@ -1,5 +1,3 @@
-#ifdef USE_ANGELSCRIPT
-
 #ifndef SCRIPTHELPER_H
 #define SCRIPTHELPER_H
 
@@ -18,8 +16,13 @@
 // The caller can optionally provide its own context, for example if a context 
should be reused.
 int ExecuteString(asIScriptEngine *engine, const char *code, asIScriptModule 
*mod = 0, asIScriptContext *ctx = 0);
 
+// Write the registered application interface to a file for an offline 
compiler.
+// The format is compatible with the offline compiler in /sdk/samples/asbuild/.
+int WriteConfigToFile(asIScriptEngine *engine, const char *filename);
+
+// Print details of the script exception to the standard output
+void PrintException(asIScriptContext *ctx, bool printStack = false);
+
 END_AS_NAMESPACE
 
-#endif //SCRIPTHELPER_H
-
-#endif // USE_ANGELSCRIPT
\ No newline at end of file
+#endif

Modified: trunk/source/main/angelscript/scriptmath/scriptmath.cpp
===================================================================
--- trunk/source/main/angelscript/scriptmath/scriptmath.cpp     2010-10-06 
16:06:18 UTC (rev 1541)
+++ trunk/source/main/angelscript/scriptmath/scriptmath.cpp     2010-12-11 
11:40:06 UTC (rev 1542)
@@ -1,10 +1,51 @@
-#ifdef USE_ANGELSCRIPT
-
 #include <assert.h>
 #include <math.h>
 #include <string.h>
 #include "scriptmath.h"
 
+#ifdef __BORLANDC__
+#include <cmath>
+
+// The C++Builder RTL doesn't pull the *f functions into the global namespace 
per default.
+using namespace std;
+
+#if __BORLANDC__ < 0x580
+// C++Builder 6 and earlier don't come with any *f variants of the math 
functions at all.
+inline float cosf (float arg) { return std::cos (arg); }
+inline float sinf (float arg) { return std::sin (arg); }
+inline float tanf (float arg) { return std::tan (arg); }
+inline float atan2f (float y, float x) { return std::atan2 (y, x); }
+inline float logf (float arg) { return std::log (arg); }
+inline float powf (float x, float y) { return std::pow (x, y); }
+inline float sqrtf (float arg) { return std::sqrt (arg); }
+#endif
+
+// C++Builder doesn't define most of the non-standard float-specific math 
functions with
+// "*f" suffix; instead it provides overloads for the standard math functions 
which take
+// "float" arguments.
+inline float acosf (float arg) { return std::acos (arg); }
+inline float asinf (float arg) { return std::asin (arg); }
+inline float atanf (float arg) { return std::atan (arg); }
+inline float coshf (float arg) { return std::cosh (arg); }
+inline float sinhf (float arg) { return std::sinh (arg); }
+inline float tanhf (float arg) { return std::tanh (arg); }
+inline float log10f (float arg) { return std::log10 (arg); }
+inline float ceilf (float arg) { return std::ceil (arg); }
+inline float fabsf (float arg) { return std::fabs (arg); }
+inline float floorf (float arg) { return std::floor (arg); }
+
+// C++Builder doesn't define a non-standard "modff" function but rather an 
overload of "modf"
+// for float arguments. However, BCC's float overload of fmod() is broken (QC 
#74816; fixed
+// in C++Builder 2010).
+inline float modff (float x, float *y)
+{
+       double d;
+       float f = (float) modf((double) x, &d);
+       *y = (float) d;
+       return f;
+}
+#endif
+
 BEGIN_AS_NAMESPACE
 
 // Determine whether the float version should be registered, or the double 
version
@@ -235,4 +276,3 @@
 END_AS_NAMESPACE
 
 
-#endif //USE_ANGELSCRIPT

Modified: trunk/source/main/angelscript/scriptmath3d/scriptmath3d.cpp
===================================================================
--- trunk/source/main/angelscript/scriptmath3d/scriptmath3d.cpp 2010-10-06 
16:06:18 UTC (rev 1541)
+++ trunk/source/main/angelscript/scriptmath3d/scriptmath3d.cpp 2010-12-11 
11:40:06 UTC (rev 1542)
@@ -1,11 +1,15 @@
-#ifdef USE_ANGELSCRIPT
-
 #include <assert.h>
 #include <string.h> // strstr
 #include <new> // new()
 #include <math.h>
 #include "scriptmath3d.h"
 
+#ifdef __BORLANDC__
+// C++Builder doesn't define a non-standard "sqrtf" function but rather an 
overload of "sqrt"
+// for float arguments.
+inline float sqrtf (float x) { return sqrt (x); }
+#endif
+
 BEGIN_AS_NAMESPACE
 
 Vector3::Vector3()
@@ -331,4 +335,3 @@
 END_AS_NAMESPACE
 
 
-#endif //USE_ANGELSCRIPT

Modified: trunk/source/main/angelscript/scriptstdstring/scriptstdstring.cpp
===================================================================
--- trunk/source/main/angelscript/scriptstdstring/scriptstdstring.cpp   
2010-10-06 16:06:18 UTC (rev 1541)
+++ trunk/source/main/angelscript/scriptstdstring/scriptstdstring.cpp   
2010-12-11 11:40:06 UTC (rev 1542)
@@ -1,5 +1,3 @@
-#ifdef USE_ANGELSCRIPT
-
 #include <assert.h>
 #include <sstream>
 #include "scriptstdstring.h"
@@ -154,6 +152,16 @@
        gen->SetReturnAddress(self);
 }
 
+void AssignBool2StringGeneric(asIScriptGeneric *gen) 
+{
+       bool *a = static_cast<bool*>(gen->GetAddressOfArg(0));
+       string *self = static_cast<string*>(gen->GetObject());
+       std::stringstream sstr;
+       sstr << *a ? "true" : "false";
+       *self = sstr.str();
+       gen->SetReturnAddress(self);
+}
+
 void AddAssignDouble2StringGeneric(asIScriptGeneric * gen) {
   double * a = static_cast<double *>(gen->GetAddressOfArg(0));
   string * self = static_cast<string *>(gen->GetObject());
@@ -181,6 +189,15 @@
   gen->SetReturnAddress(self);
 }
 
+void AddAssignBool2StringGeneric(asIScriptGeneric * gen) {
+  bool * a = static_cast<bool *>(gen->GetAddressOfArg(0));
+  string * self = static_cast<string *>(gen->GetObject());
+  std::stringstream sstr;
+  sstr << *a ? "true" : "false";
+  *self += sstr.str();
+  gen->SetReturnAddress(self);
+}
+
 void AddString2DoubleGeneric(asIScriptGeneric * gen) {
   string * a = static_cast<string *>(gen->GetObject());
   double * b = static_cast<double *>(gen->GetAddressOfArg(0));
@@ -208,6 +225,15 @@
   gen->SetReturnObject(&ret_val);
 }
 
+void AddString2BoolGeneric(asIScriptGeneric * gen) {
+  string * a = static_cast<string *>(gen->GetObject());
+  bool * b = static_cast<bool *>(gen->GetAddressOfArg(0));
+  std::stringstream sstr;
+  sstr << *a << *b ? "true" : "false";
+  std::string ret_val = sstr.str();
+  gen->SetReturnObject(&ret_val);
+}
+
 void AddDouble2StringGeneric(asIScriptGeneric * gen) {
   double* a = static_cast<double *>(gen->GetAddressOfArg(0));
   string * b = static_cast<string *>(gen->GetObject());
@@ -235,7 +261,16 @@
   gen->SetReturnObject(&ret_val);
 }
 
+void AddBool2StringGeneric(asIScriptGeneric * gen) {
+  bool* a = static_cast<bool *>(gen->GetAddressOfArg(0));
+  string * b = static_cast<string *>(gen->GetObject());
+  std::stringstream sstr;
+  sstr << (*a ? "true" : "false") << *b;
+  std::string ret_val = sstr.str();
+  gen->SetReturnObject(&ret_val);
+}
 
+
 void RegisterStdString_Generic(asIScriptEngine *engine) {
   int r;
 
@@ -265,8 +300,8 @@
   }
 
   // Register the index operator, both as a mutator and as an inspector
-  r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "uint8 
&f(uint)", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 );
-  r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "const uint8 
&f(uint) const", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 
0 );
+  r = engine->RegisterObjectMethod("string", "uint8 &opIndex(uint)", 
asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 );
+  r = engine->RegisterObjectMethod("string", "const uint8 &opIndex(uint) 
const", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 );
 
   // Automatic conversion from values
   r = engine->RegisterObjectMethod("string", "string &opAssign(double)", 
asFUNCTION(AssignDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
@@ -283,6 +318,11 @@
   r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint)", 
asFUNCTION(AddAssignUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
   r = engine->RegisterObjectMethod("string", "string opAdd(uint) const", 
asFUNCTION(AddString2UIntGeneric), asCALL_GENERIC); assert( r >= 0 );
   r = engine->RegisterObjectMethod("string", "string opAdd_r(uint) const", 
asFUNCTION(AddUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
+
+  r = engine->RegisterObjectMethod("string", "string &opAssign(bool)", 
asFUNCTION(AssignBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
+  r = engine->RegisterObjectMethod("string", "string &opAddAssign(bool)", 
asFUNCTION(AddAssignBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
+  r = engine->RegisterObjectMethod("string", "string opAdd(bool) const", 
asFUNCTION(AddString2BoolGeneric), asCALL_GENERIC); assert( r >= 0 );
+  r = engine->RegisterObjectMethod("string", "string opAdd_r(bool) const", 
asFUNCTION(AddBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
 }
 
 static string StringFactory(asUINT length, const char *s)
@@ -378,6 +418,22 @@
        return dest;
 }
 
+static string &AssignBoolToString(bool b, string &dest)
+{
+       ostringstream stream;
+       stream << b ? "true" : "false";
+       dest = stream.str();
+       return dest;
+}
+
+static string &AddAssignBoolToString(bool b, string &dest)
+{
+       ostringstream stream;
+       stream << b ? "true" : "false";
+       dest += stream.str();
+       return dest;
+}
+
 static string AddStringDouble(string &str, double f)
 {
        ostringstream stream;
@@ -393,6 +449,21 @@
        return stream.str() + str;
 }
 
+static string AddStringBool(string &str, bool b)
+{
+       ostringstream stream;
+       stream << b ? "true" : "false";
+       str += stream.str();
+       return str;
+}
+
+static string AddBoolString(bool b, string &str)
+{
+       ostringstream stream;
+       stream << b ? "true" : "false";
+       return stream.str() + str;
+}
+
 static char *StringCharAt(unsigned int i, string &str)
 {
        if( i >= str.size() )
@@ -450,8 +521,8 @@
 
        // Register the index operator, both as a mutator and as an inspector
        // Note that we don't register the operator[] directory, as it doesn't 
do bounds checking
-       r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "uint8 
&f(uint)", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 );
-       r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "const 
uint8 &f(uint) const", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( 
r >= 0 );
+       r = engine->RegisterObjectMethod("string", "uint8 &opIndex(uint)", 
asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 );
+       r = engine->RegisterObjectMethod("string", "const uint8 &opIndex(uint) 
const", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 );
 
        // Automatic conversion from values
        r = engine->RegisterObjectMethod("string", "string &opAssign(double)", 
asFUNCTION(AssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
@@ -468,6 +539,11 @@
        r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint)", 
asFUNCTION(AddAssignUIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
        r = engine->RegisterObjectMethod("string", "string opAdd(uint) const", 
asFUNCTION(AddStringUInt), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
        r = engine->RegisterObjectMethod("string", "string opAdd_r(uint) 
const", asFUNCTION(AddUIntString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
+
+       r = engine->RegisterObjectMethod("string", "string &opAssign(bool)", 
asFUNCTION(AssignBoolToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
+       r = engine->RegisterObjectMethod("string", "string &opAddAssign(bool)", 
asFUNCTION(AddAssignBoolToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
+       r = engine->RegisterObjectMethod("string", "string opAdd(bool) const", 
asFUNCTION(AddStringBool), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
+       r = engine->RegisterObjectMethod("string", "string opAdd_r(bool) 
const", asFUNCTION(AddBoolString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
 }
 
 void RegisterStdString(asIScriptEngine * engine)
@@ -480,4 +556,6 @@
 
 END_AS_NAMESPACE
 
-#endif //USE_ANGELSCRIPT
+
+
+

Modified: trunk/source/main/angelscript/scriptstdstring/scriptstdstring.h
===================================================================
--- trunk/source/main/angelscript/scriptstdstring/scriptstdstring.h     
2010-10-06 16:06:18 UTC (rev 1541)
+++ trunk/source/main/angelscript/scriptstdstring/scriptstdstring.h     
2010-12-11 11:40:06 UTC (rev 1542)
@@ -1,5 +1,3 @@
-#ifdef USE_ANGELSCRIPT
-
 //
 // Script std::string
 //
@@ -23,5 +21,3 @@
 END_AS_NAMESPACE
 
 #endif
-
-#endif //USE_ANGELSCRIPT


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Oracle to DB2 Conversion Guide: Learn learn about native support for PL/SQL,
new data types, scalar functions, improved concurrency, built-in packages, 
OCI, SQL*Plus, data movement tools, best practices and more.
http://p.sf.net/sfu/oracle-sfdev2dev 
_______________________________________________
Rigsofrods-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rigsofrods-devel

Reply via email to