зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug 84186. r=dbradley, jag. sr=jband. Added support for CStrings, UTF8String, and AStrings to XPIDL. Also added the -t cmd line flag to XPIDL and XPTLINK that allows us to generate output for a specific XPT version. The XPT version number is being upped from 1.1 to 1.2 with this checkin.
This commit is contained in:
Родитель
86c5368302
Коммит
46db685f9a
|
@ -99,9 +99,9 @@ static uint8 xpc_reflectable_flags[XPC_FLAG_COUNT] = {
|
|||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_ARRAY */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_PSTRING_SIZE_IS */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_PWSTRING_SIZE_IS */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* 23 - reserved */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* 24 - reserved */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* 25 - reserved */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 0 ), /* T_UTF8STRING */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 0 ), /* T_CSTRING */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 0 ), /* T_ASTRING */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* 26 - reserved */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* 27 - reserved */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* 28 - reserved */
|
||||
|
@ -110,6 +110,8 @@ static uint8 xpc_reflectable_flags[XPC_FLAG_COUNT] = {
|
|||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ) /* 31 - reserved */
|
||||
};
|
||||
|
||||
static intN sXPCOMUCStringFinalizerIndex = -1;
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
// static
|
||||
|
@ -199,6 +201,40 @@ JAM_DOUBLE(JSContext *cx, double v, jsdouble *dbl)
|
|||
#define FIT_U32(cx,i,d) ((i) <= JSVAL_INT_MAX ? \
|
||||
INT_TO_JSVAL(i) : JAM_DOUBLE(cx,i,d))
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(void)
|
||||
FinalizeXPCOMUCString(JSContext *cx, JSString *str)
|
||||
{
|
||||
NS_ASSERTION(sXPCOMUCStringFinalizerIndex != -1,
|
||||
"XPCConvert: XPCOM Unicode string finalizer called uninitialized!");
|
||||
|
||||
PRUnichar* buffer = JS_GetStringChars(str);
|
||||
nsMemory::Free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static JSBool
|
||||
AddXPCOMUCStringFinalizer()
|
||||
{
|
||||
|
||||
sXPCOMUCStringFinalizerIndex =
|
||||
JS_AddExternalStringFinalizer(FinalizeXPCOMUCString);
|
||||
|
||||
if (sXPCOMUCStringFinalizerIndex == -1)
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
XPCConvert::RemoveXPCOMUCStringFinalizer()
|
||||
{
|
||||
JS_RemoveExternalStringFinalizer(FinalizeXPCOMUCString);
|
||||
sXPCOMUCStringFinalizerIndex = -1;
|
||||
}
|
||||
|
||||
// static
|
||||
JSBool
|
||||
XPCConvert::NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
|
||||
|
@ -283,6 +319,9 @@ XPCConvert::NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
|
|||
break;
|
||||
}
|
||||
|
||||
case nsXPTType::T_ASTRING:
|
||||
// Fall through to T_DOMSTRING case
|
||||
|
||||
case nsXPTType::T_DOMSTRING:
|
||||
{
|
||||
const nsAReadableString* p = *((const nsAReadableString**)s);
|
||||
|
@ -337,6 +376,69 @@ XPCConvert::NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
|
|||
*d = STRING_TO_JSVAL(str);
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_UTF8STRING:
|
||||
{
|
||||
const nsAReadableCString* cString = *((const nsAReadableCString**)s);
|
||||
|
||||
if(!cString)
|
||||
break;
|
||||
|
||||
if(!cString->IsVoid())
|
||||
{
|
||||
// XXX There is an extra copy happening here. When the
|
||||
// UTF8String implementation lands, it should contain
|
||||
// a mechanism to avoid this extra copy. Jag will change
|
||||
// this code to use that new mechanism when he lands the
|
||||
// UTF8String changes.
|
||||
NS_ConvertUTF8toUCS2 unicodeString(*cString);
|
||||
|
||||
JSString* jsString = JS_NewUCStringCopyN(cx,
|
||||
NS_CONST_CAST(jschar*,
|
||||
unicodeString.get()),
|
||||
unicodeString.Length());
|
||||
|
||||
if(!jsString)
|
||||
return JS_FALSE;
|
||||
|
||||
*d = STRING_TO_JSVAL(jsString);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
case nsXPTType::T_CSTRING:
|
||||
{
|
||||
const nsAReadableCString* cString = *((const nsAReadableCString**)s);
|
||||
|
||||
if(!cString)
|
||||
break;
|
||||
|
||||
if(!cString->IsVoid())
|
||||
{
|
||||
PRUnichar* unicodeString = ToNewUnicode(*cString);
|
||||
if(!unicodeString)
|
||||
return JS_FALSE;
|
||||
|
||||
if(sXPCOMUCStringFinalizerIndex == -1 &&
|
||||
!AddXPCOMUCStringFinalizer())
|
||||
return JS_FALSE;
|
||||
|
||||
JSString* jsString = JS_NewExternalString(cx,
|
||||
unicodeString,
|
||||
cString->Length(),
|
||||
sXPCOMUCStringFinalizerIndex);
|
||||
|
||||
if(!jsString)
|
||||
{
|
||||
nsMemory::Free(unicodeString);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*d = STRING_TO_JSVAL(jsString);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case nsXPTType::T_INTERFACE:
|
||||
case nsXPTType::T_INTERFACE_IS:
|
||||
|
@ -379,6 +481,7 @@ XPCConvert::NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
|
|||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// static
|
||||
JSBool
|
||||
XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
|
||||
|
@ -393,6 +496,7 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
|
|||
int32 ti;
|
||||
uint32 tu;
|
||||
jsdouble td;
|
||||
JSBool isDOMString = JS_TRUE;
|
||||
|
||||
if(pErr)
|
||||
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
|
@ -549,6 +653,11 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
case nsXPTType::T_ASTRING:
|
||||
{
|
||||
isDOMString = JS_FALSE;
|
||||
// Fall through to T_DOMSTRING case.
|
||||
}
|
||||
case nsXPTType::T_DOMSTRING:
|
||||
{
|
||||
static const NS_NAMED_LITERAL_STRING(sEmptyString, "");
|
||||
|
@ -561,8 +670,16 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
|
|||
|
||||
if(JSVAL_IS_VOID(s))
|
||||
{
|
||||
chars = sVoidString.get();
|
||||
length = sVoidString.Length();
|
||||
if(isDOMString)
|
||||
{
|
||||
chars = sVoidString.get();
|
||||
length = sVoidString.Length();
|
||||
}
|
||||
else
|
||||
{
|
||||
chars = sEmptyString.get();
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
else if(!JSVAL_IS_NULL(s))
|
||||
{
|
||||
|
@ -623,7 +740,7 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
|
|||
{
|
||||
nsAWritableString* ws = *((nsAWritableString**)d);
|
||||
|
||||
if(JSVAL_IS_NULL(s))
|
||||
if(JSVAL_IS_NULL(s) || (!isDOMString && JSVAL_IS_VOID(s)))
|
||||
{
|
||||
ws->Truncate();
|
||||
ws->SetIsVoid(PR_TRUE);
|
||||
|
@ -726,6 +843,116 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
case nsXPTType::T_UTF8STRING:
|
||||
{
|
||||
jschar* chars;
|
||||
PRUint32 length;
|
||||
JSString* str;
|
||||
|
||||
if(JSVAL_IS_NULL(s) || JSVAL_IS_VOID(s))
|
||||
{
|
||||
if(useAllocator)
|
||||
{
|
||||
nsACString *rs = new nsCString();
|
||||
if(!rs)
|
||||
return JS_FALSE;
|
||||
|
||||
rs->SetIsVoid(PR_TRUE);
|
||||
*((nsACString**)d) = rs;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCString* rs = *((nsCString**)d);
|
||||
rs->Truncate();
|
||||
rs->SetIsVoid(PR_TRUE);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// The JS val is neither null nor void...
|
||||
|
||||
if(!(str = JS_ValueToString(cx, s))||
|
||||
!(chars = JS_GetStringChars(str)))
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
length = JS_GetStringLength(str);
|
||||
|
||||
if(useAllocator)
|
||||
{
|
||||
nsAReadableCString *rs = new NS_ConvertUCS2toUTF8(chars, length);
|
||||
if(!rs)
|
||||
return JS_FALSE;
|
||||
|
||||
*((nsAReadableCString**)d) = rs;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCString* rs = *((nsCString**)d);
|
||||
|
||||
// XXX This code needs to change when Jag lands the new
|
||||
// UTF8String implementation. Adopt() is a method that
|
||||
// shouldn't be used by string consumers.
|
||||
rs->Adopt(ToNewUTF8String(nsDependentString(chars, length)));
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
case nsXPTType::T_CSTRING:
|
||||
{
|
||||
const char* chars;
|
||||
PRUint32 length;
|
||||
JSString* str;
|
||||
|
||||
if(JSVAL_IS_NULL(s) || JSVAL_IS_VOID(s))
|
||||
{
|
||||
if(useAllocator)
|
||||
{
|
||||
nsACString *rs = new nsCString();
|
||||
if(!rs)
|
||||
return JS_FALSE;
|
||||
|
||||
rs->SetIsVoid(PR_TRUE);
|
||||
*((nsACString**)d) = rs;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsACString* rs = *((nsACString**)d);
|
||||
rs->Truncate();
|
||||
rs->SetIsVoid(PR_TRUE);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// The JS val is neither null nor void...
|
||||
|
||||
if(!(str = JS_ValueToString(cx, s)) ||
|
||||
!(chars = JS_GetStringBytes(str)))
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
length = JS_GetStringLength(str);
|
||||
|
||||
if(useAllocator)
|
||||
{
|
||||
nsAReadableCString *rs = new nsCString(chars, length);
|
||||
|
||||
if(!rs)
|
||||
return JS_FALSE;
|
||||
|
||||
*((nsAReadableCString**)d) = rs;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsACString* rs = *((nsACString**)d);
|
||||
|
||||
rs->Assign(nsDependentCString(chars, length));
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
case nsXPTType::T_INTERFACE:
|
||||
case nsXPTType::T_INTERFACE_IS:
|
||||
{
|
||||
|
@ -1372,6 +1599,9 @@ XPCConvert::NativeArray2JS(XPCCallContext& ccx,
|
|||
case nsXPTType::T_WCHAR_STR : POPULATE(jschar*); break;
|
||||
case nsXPTType::T_INTERFACE : POPULATE(nsISupports*); break;
|
||||
case nsXPTType::T_INTERFACE_IS : POPULATE(nsISupports*); break;
|
||||
case nsXPTType::T_UTF8STRING : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
case nsXPTType::T_CSTRING : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
case nsXPTType::T_ASTRING : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
default : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
}
|
||||
|
||||
|
@ -1501,6 +1731,9 @@ fill_array:
|
|||
case nsXPTType::T_WCHAR_STR : POPULATE(fr, jschar*); break;
|
||||
case nsXPTType::T_INTERFACE : POPULATE(re, nsISupports*); break;
|
||||
case nsXPTType::T_INTERFACE_IS : POPULATE(re, nsISupports*); break;
|
||||
case nsXPTType::T_UTF8STRING : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
case nsXPTType::T_CSTRING : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
case nsXPTType::T_ASTRING : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
default : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
}
|
||||
|
||||
|
|
|
@ -718,6 +718,8 @@ XPCJSRuntime::~XPCJSRuntime()
|
|||
|
||||
// unwire the readable/JSString sharing magic
|
||||
XPCStringConvert::ShutdownDOMStringFinalizer();
|
||||
|
||||
XPCConvert::RemoveXPCOMUCStringFinalizer();
|
||||
}
|
||||
|
||||
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect,
|
||||
|
|
|
@ -2241,9 +2241,11 @@ public:
|
|||
static nsresult ConstructException(nsresult rv, const char* message,
|
||||
const char* ifaceName,
|
||||
const char* methodName,
|
||||
nsISupports* data,
|
||||
nsISupports* data,
|
||||
nsIException** exception);
|
||||
|
||||
static void RemoveXPCOMUCStringFinalizer();
|
||||
|
||||
private:
|
||||
XPCConvert(); // not implemented
|
||||
|
||||
|
|
|
@ -1789,6 +1789,9 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx,
|
|||
useAllocator = JS_TRUE;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_ASTRING:
|
||||
// Fall through to the T_DOMSTRING case
|
||||
|
||||
case nsXPTType::T_DOMSTRING:
|
||||
if(paramInfo.IsDipper())
|
||||
{
|
||||
|
@ -1823,6 +1826,25 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx,
|
|||
dp->SetValIsDOMString();
|
||||
useAllocator = JS_TRUE;
|
||||
break;
|
||||
|
||||
case nsXPTType::T_UTF8STRING:
|
||||
// Fall through to the C string case for now...
|
||||
case nsXPTType::T_CSTRING:
|
||||
dp->SetValIsCString();
|
||||
if(paramInfo.IsDipper())
|
||||
{
|
||||
// Is an 'out' CString.
|
||||
if(!(dp->val.p = new nsCString()))
|
||||
{
|
||||
JS_ReportOutOfMemory(ccx);
|
||||
goto done;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// else ...
|
||||
// Is an 'in' CString.
|
||||
useAllocator = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2167,7 +2189,11 @@ done:
|
|||
((nsISupports*)p)->Release();
|
||||
else if(dp->IsValDOMString())
|
||||
delete (nsAString*)p;
|
||||
}
|
||||
else if(dp->IsValUTF8String())
|
||||
delete (nsCString*) p;
|
||||
else if(dp->IsValCString())
|
||||
delete (nsCString*) p;
|
||||
}
|
||||
}
|
||||
|
||||
if(dispatchParams && dispatchParams != paramBuffer)
|
||||
|
@ -2411,7 +2437,7 @@ XPCWrappedNative::ToString(XPCCallContext& ccx,
|
|||
return nsnull;
|
||||
}
|
||||
const char* fmt = "[xpconnect wrapped %s" FMT_ADDR "]";
|
||||
if (si)
|
||||
if(si)
|
||||
{
|
||||
fmt = "[object %s" FMT_ADDR "]";
|
||||
}
|
||||
|
|
|
@ -122,6 +122,58 @@ NS_IMETHODIMP xpctestEcho::EchoIn2OutOneDOMString(const nsAReadableString & inpu
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* AString In2OutOneAString (in AString input); */
|
||||
NS_IMETHODIMP xpctestEcho::In2OutOneAString(const nsAString & input,
|
||||
nsAString & _retval)
|
||||
{
|
||||
_retval.Assign(input);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* AString EchoIn2OutOneAString (in AString input); */
|
||||
NS_IMETHODIMP xpctestEcho::EchoIn2OutOneAString(const nsAString & input, nsAString & _retval)
|
||||
{
|
||||
if(mReceiver)
|
||||
return mReceiver->EchoIn2OutOneAString(input, _retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* UTF8String In2OutOneUTF8String (in UTF8String input); */
|
||||
NS_IMETHODIMP xpctestEcho::In2OutOneUTF8String(const nsACString & input,
|
||||
nsACString & _retval)
|
||||
{
|
||||
_retval.Assign(input);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* UTF8String EchoIn2OutOneUTF8String (in UTF8String input); */
|
||||
NS_IMETHODIMP xpctestEcho::EchoIn2OutOneUTF8String(const nsACString & input,
|
||||
nsACString & _retval)
|
||||
{
|
||||
if(mReceiver)
|
||||
return mReceiver->EchoIn2OutOneUTF8String(input, _retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* CString In2OutOneCString (in CString input); */
|
||||
NS_IMETHODIMP xpctestEcho::In2OutOneCString(const nsACString & input,
|
||||
nsACString & _retval)
|
||||
{
|
||||
_retval.Assign(input);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* CString EchoIn2OutOneCString (in CString input); */
|
||||
NS_IMETHODIMP xpctestEcho::EchoIn2OutOneCString(const nsACString & input,
|
||||
nsACString & _retval)
|
||||
{
|
||||
if(mReceiver)
|
||||
return mReceiver->EchoIn2OutOneCString(input, _retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP xpctestEcho::In2OutAddTwoInts(int input1,
|
||||
int input2,
|
||||
int* output1,
|
||||
|
|
|
@ -66,7 +66,6 @@ interface nsITestXPCFoo2 : nsITestXPCFoo {
|
|||
|
||||
[scriptable, uuid(CD2F2F40-C5D9-11d2-9838-006008962422)]
|
||||
interface nsIEcho : nsISupports {
|
||||
|
||||
void SetReceiver(in nsIEcho aReceiver);
|
||||
void SendOneString(in string str);
|
||||
long In2OutOneInt(in long input);
|
||||
|
@ -79,6 +78,15 @@ interface nsIEcho : nsISupports {
|
|||
DOMString In2OutOneDOMString(in DOMString input);
|
||||
DOMString EchoIn2OutOneDOMString(in DOMString input);
|
||||
|
||||
AString In2OutOneAString(in AString input);
|
||||
AString EchoIn2OutOneAString(in AString input);
|
||||
|
||||
AUTF8String In2OutOneUTF8String(in AUTF8String input);
|
||||
AUTF8String EchoIn2OutOneUTF8String(in AUTF8String input);
|
||||
|
||||
ACString In2OutOneCString(in ACString input);
|
||||
ACString EchoIn2OutOneCString(in ACString input);
|
||||
|
||||
void SimpleCallNoEcho();
|
||||
void SendManyTypes(in octet p1,
|
||||
in short p2,
|
||||
|
|
|
@ -76,6 +76,24 @@ receiver.EchoIn2OutOneDOMString = function(input)
|
|||
return input;
|
||||
};
|
||||
|
||||
receiver.EchoIn2OutOneAString = function(input)
|
||||
{
|
||||
// print("EchoIn2OutOneAString called with: "+input);
|
||||
return input;
|
||||
};
|
||||
|
||||
receiver.EchoIn2OutOneUTF8String = function(input)
|
||||
{
|
||||
// print("EchoIn2OutOneUTF8String called with: "+input);
|
||||
return input;
|
||||
}
|
||||
|
||||
receiver.EchoIn2OutOneCString = function(input)
|
||||
{
|
||||
// print("EchoIn2OutOneCString called with: "+input);
|
||||
return input;
|
||||
}
|
||||
|
||||
echo.SetReceiver(receiver);
|
||||
|
||||
////////////////////
|
||||
|
@ -224,6 +242,7 @@ if(all_ok)
|
|||
print("SendInOutManyTypes - passed");
|
||||
|
||||
////////////////////
|
||||
// Test DOMString
|
||||
|
||||
var test_string3 = "And this is yet again some other string 3";
|
||||
var test_string4 = "And this is yet again some other string 4";
|
||||
|
@ -248,6 +267,78 @@ print("EchoIn2OutOneDOMString of undefined - "+(
|
|||
echo.EchoIn2OutOneDOMString(this.propertyThatDoesNotExist) == "undefined"
|
||||
? "passed" : "failed"));
|
||||
|
||||
/////////////////////
|
||||
// Test AString
|
||||
|
||||
print("In2OutOneAString - "+(
|
||||
echo.In2OutOneAString(test_string3) == test_string3
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneAString - "+(
|
||||
echo.EchoIn2OutOneAString(test_string4) == test_string4
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneAString of empty string - "+(
|
||||
echo.EchoIn2OutOneAString("") == ""
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneAString of null - "+(
|
||||
echo.EchoIn2OutOneAString(null) == null
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneAString of undefined - "+(
|
||||
echo.EchoIn2OutOneAString(this.propertyThatDoesNotExist) == ""
|
||||
? "passed" : "failed"));
|
||||
|
||||
/////////////////////
|
||||
// Test AUTF8String
|
||||
|
||||
var test_utf8String =
|
||||
"Non-Ascii 1 byte chars: éâäàåç, 2 byte chars: \u1234 \u1235 \u1236";
|
||||
|
||||
print("In2OutOneUTF8String - "+(
|
||||
echo.In2OutOneUTF8String(test_utf8String) == test_utf8String
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneUTF8String - "+(
|
||||
echo.EchoIn2OutOneUTF8String(test_utf8String) == test_utf8String
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneUTF8String of empty string - "+(
|
||||
echo.EchoIn2OutOneUTF8String("") == ""
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneUTF8String of null - "+(
|
||||
echo.EchoIn2OutOneUTF8String(null) == null
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneUTF8String of undefined - "+(
|
||||
echo.EchoIn2OutOneUTF8String(this.propertyThatDoesNotExist) == ""
|
||||
? "passed" : "failed"));
|
||||
|
||||
/////////////////////
|
||||
// Test ACString
|
||||
|
||||
print("In2OutOneCString - "+(
|
||||
echo.In2OutOneCString(test_string3) == test_string3
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneCString - "+(
|
||||
echo.EchoIn2OutOneCString(test_string4) == test_string4
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneCString of empty string - "+(
|
||||
echo.EchoIn2OutOneCString("") == ""
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneCString of null - "+(
|
||||
echo.EchoIn2OutOneCString(null) == null
|
||||
? "passed" : "failed"));
|
||||
|
||||
print("EchoIn2OutOneCString of undefined - "+(
|
||||
echo.EchoIn2OutOneCString(this.propertyThatDoesNotExist) == ""
|
||||
? "passed" : "failed"));
|
||||
|
||||
////////////////////
|
||||
// check exceptions on xpcom error code
|
||||
|
||||
|
|
|
@ -102,9 +102,17 @@ typedef unsigned long size_t;
|
|||
[ref, domstring] native DOMStringRef(ignored);
|
||||
[ptr, domstring] native DOMStringPtr(ignored);
|
||||
|
||||
[ref, domstring] native AString(ignored);
|
||||
[ref, domstring] native AStringRef(ignored);
|
||||
[ptr, domstring] native AStringPtr(ignored);
|
||||
[ref, utf8string] native AUTF8String(ignored);
|
||||
[ref, utf8string] native AUTF8StringRef(ignored);
|
||||
[ptr, utf8string] native AUTF8StringPtr(ignored);
|
||||
|
||||
[ref, cstring] native ACString(ignored);
|
||||
[ref, cstring] native ACStringRef(ignored);
|
||||
[ptr, cstring] native ACStringPtr(ignored);
|
||||
|
||||
[ref, astring] native AString(ignored);
|
||||
[ref, astring] native AStringRef(ignored);
|
||||
[ptr, astring] native AStringPtr(ignored);
|
||||
|
||||
%{C++
|
||||
/*
|
||||
|
|
|
@ -113,25 +113,31 @@ struct nsXPTCVariant : public nsXPTCMiniVariant
|
|||
enum
|
||||
{
|
||||
// these are bitflags!
|
||||
PTR_IS_DATA = 0x1, // ptr points to 'real' data in val
|
||||
VAL_IS_ALLOCD= 0x2, // val.p holds alloc'd ptr that must be freed
|
||||
VAL_IS_IFACE = 0x4, // val.p holds interface ptr that must be released
|
||||
VAL_IS_ARRAY = 0x8, // val.p holds a pointer to an array needing cleanup
|
||||
VAL_IS_DOMSTR= 0x10 // val.p holds a pointer to domstring needing cleanup
|
||||
PTR_IS_DATA = 0x1, // ptr points to 'real' data in val
|
||||
VAL_IS_ALLOCD = 0x2, // val.p holds alloc'd ptr that must be freed
|
||||
VAL_IS_IFACE = 0x4, // val.p holds interface ptr that must be released
|
||||
VAL_IS_ARRAY = 0x8, // val.p holds a pointer to an array needing cleanup
|
||||
VAL_IS_DOMSTR = 0x10, // val.p holds a pointer to domstring needing cleanup
|
||||
VAL_IS_UTF8STR = 0x20, // val.p holds a pointer to utf8string needing cleanup
|
||||
VAL_IS_CSTR = 0x40 // val.p holds a pointer to cstring needing cleanup
|
||||
};
|
||||
|
||||
void ClearFlags() {flags = 0;}
|
||||
void SetPtrIsData() {flags |= PTR_IS_DATA;}
|
||||
void SetValIsAllocated() {flags |= VAL_IS_ALLOCD;}
|
||||
void SetValIsInterface() {flags |= VAL_IS_IFACE;}
|
||||
void SetValIsArray() {flags |= VAL_IS_ARRAY;}
|
||||
void SetValIsDOMString() {flags |= VAL_IS_DOMSTR;}
|
||||
void ClearFlags() {flags = 0;}
|
||||
void SetPtrIsData() {flags |= PTR_IS_DATA;}
|
||||
void SetValIsAllocated() {flags |= VAL_IS_ALLOCD;}
|
||||
void SetValIsInterface() {flags |= VAL_IS_IFACE;}
|
||||
void SetValIsArray() {flags |= VAL_IS_ARRAY;}
|
||||
void SetValIsDOMString() {flags |= VAL_IS_DOMSTR;}
|
||||
void SetValIsUTF8String() {flags |= VAL_IS_UTF8STR;}
|
||||
void SetValIsCString() {flags |= VAL_IS_CSTR;}
|
||||
|
||||
PRBool IsPtrData() const {return 0 != (flags & PTR_IS_DATA);}
|
||||
PRBool IsValAllocated() const {return 0 != (flags & VAL_IS_ALLOCD);}
|
||||
PRBool IsValInterface() const {return 0 != (flags & VAL_IS_IFACE);}
|
||||
PRBool IsValArray() const {return 0 != (flags & VAL_IS_ARRAY);}
|
||||
PRBool IsValDOMString() const {return 0 != (flags & VAL_IS_DOMSTR);}
|
||||
PRBool IsPtrData() const {return 0 != (flags & PTR_IS_DATA);}
|
||||
PRBool IsValAllocated() const {return 0 != (flags & VAL_IS_ALLOCD);}
|
||||
PRBool IsValInterface() const {return 0 != (flags & VAL_IS_IFACE);}
|
||||
PRBool IsValArray() const {return 0 != (flags & VAL_IS_ARRAY);}
|
||||
PRBool IsValDOMString() const {return 0 != (flags & VAL_IS_DOMSTR);}
|
||||
PRBool IsValUTF8String() const {return 0 != (flags & VAL_IS_UTF8STR);}
|
||||
PRBool IsValCString() const {return 0 != (flags & VAL_IS_CSTR);}
|
||||
|
||||
void Init(const nsXPTCMiniVariant& mv, const nsXPTType& t, PRUint8 f)
|
||||
{
|
||||
|
@ -170,6 +176,8 @@ struct nsXPTCVariant : public nsXPTCMiniVariant
|
|||
case nsXPTType::T_ARRAY: /* fall through */
|
||||
case nsXPTType::T_PSTRING_SIZE_IS: /* fall through */
|
||||
case nsXPTType::T_PWSTRING_SIZE_IS: /* fall through */
|
||||
case nsXPTType::T_UTF8STRING: /* fall through */
|
||||
case nsXPTType::T_CSTRING: /* fall through */
|
||||
default: val.p = mv.val.p; break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,9 @@ TypesArray dd t_Int4Bytes ; nsXPTType::T_I8
|
|||
dd t_Int4Bytes ; TD_ARRAY
|
||||
dd t_Int4Bytes ; TD_PSTRING_SIZE_IS
|
||||
dd t_Int4Bytes ; TD_PWSTRING_SIZE_IS
|
||||
dd t_Int4Bytes ; TD_UTF8STRING
|
||||
dd t_Int4Bytes ; TD_CSTRING
|
||||
dd t_Int4Bytes ; TD_ASTRING
|
||||
; All other values default to 4 byte int/ptr
|
||||
|
||||
|
||||
|
|
|
@ -176,7 +176,10 @@ public:
|
|||
T_INTERFACE_IS = TD_INTERFACE_IS_TYPE,
|
||||
T_ARRAY = TD_ARRAY ,
|
||||
T_PSTRING_SIZE_IS = TD_PSTRING_SIZE_IS ,
|
||||
T_PWSTRING_SIZE_IS = TD_PWSTRING_SIZE_IS
|
||||
T_PWSTRING_SIZE_IS = TD_PWSTRING_SIZE_IS ,
|
||||
T_UTF8STRING = TD_UTF8STRING ,
|
||||
T_CSTRING = TD_CSTRING ,
|
||||
T_ASTRING = TD_ASTRING
|
||||
};
|
||||
// NO DATA - this a flyweight wrapper
|
||||
};
|
||||
|
|
|
@ -60,18 +60,23 @@ FindMode(char *mode)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
gboolean enable_debug = FALSE;
|
||||
gboolean enable_warnings = FALSE;
|
||||
gboolean verbose_mode = FALSE;
|
||||
gboolean emit_typelib_annotations = FALSE;
|
||||
gboolean explicit_output_filename = FALSE;
|
||||
gboolean enable_debug = FALSE;
|
||||
gboolean enable_warnings = FALSE;
|
||||
gboolean verbose_mode = FALSE;
|
||||
gboolean emit_typelib_annotations = FALSE;
|
||||
gboolean explicit_output_filename = FALSE;
|
||||
|
||||
/* The following globals are explained in xpt_struct.h */
|
||||
PRUint8 major_version = XPT_MAJOR_VERSION;
|
||||
PRUint8 minor_version = XPT_MINOR_VERSION;
|
||||
|
||||
static char xpidl_usage_str[] =
|
||||
"Usage: %s [-m mode] [-w] [-v]\n"
|
||||
"Usage: %s [-m mode] [-w] [-v] [-t version number]\n"
|
||||
" [-I path] [-o basename | -e filename.ext] filename.idl\n"
|
||||
" -a emit annotations to typelib\n"
|
||||
" -w turn on warnings (recommended)\n"
|
||||
" -v verbose mode (NYI)\n"
|
||||
" -t create a typelib of a specific version number\n"
|
||||
" -I add entry to start of include path for ``#include \"nsIThing.idl\"''\n"
|
||||
" -o use basename (e.g. ``/tmp/nsIThing'') for output\n"
|
||||
" -e use explicit output filename\n"
|
||||
|
@ -99,6 +104,7 @@ int main(int argc, char *argv[])
|
|||
IncludePathEntry *inc, *inc_head, **inc_tail;
|
||||
char *file_basename = NULL;
|
||||
ModeData *mode = NULL;
|
||||
gboolean create_old_typelib = FALSE;
|
||||
|
||||
/* turn this on for extra checking of our code */
|
||||
/* IDL_check_cast_enable(TRUE); */
|
||||
|
@ -130,6 +136,58 @@ int main(int argc, char *argv[])
|
|||
case 'v':
|
||||
verbose_mode = TRUE;
|
||||
break;
|
||||
case 't':
|
||||
{
|
||||
/* Parse for "-t version number" and store it into global boolean
|
||||
* and string variables.
|
||||
*/
|
||||
const gchar* typelib_version_string = NULL;
|
||||
|
||||
/*
|
||||
* If -t is the last argument on the command line, we have a problem
|
||||
*/
|
||||
|
||||
if (i + 1 == argc) {
|
||||
fprintf(stderr, "ERROR: missing version number after -t\n");
|
||||
xpidl_usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Do not allow more than one "-t" definition */
|
||||
if (create_old_typelib) {
|
||||
fprintf(stderr,
|
||||
"ERROR: -t argument used twice. "
|
||||
"Cannot specify more than one version\n");
|
||||
xpidl_usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that the argument after "-t" is the version number string
|
||||
* and search for it in our internal list of acceptable version
|
||||
* numbers.
|
||||
*/
|
||||
switch (XPT_ParseVersionString(argv[++i], &major_version,
|
||||
&minor_version)) {
|
||||
case XPT_VERSION_CURRENT:
|
||||
break;
|
||||
case XPT_VERSION_OLD:
|
||||
create_old_typelib = TRUE;
|
||||
break;
|
||||
case XPT_VERSION_UNSUPPORTED:
|
||||
fprintf(stderr, "ERROR: version \"%s\" not supported.\n",
|
||||
argv[i]);
|
||||
xpidl_usage(argc, argv);
|
||||
return 1;
|
||||
case XPT_VERSION_UNKNOWN:
|
||||
default:
|
||||
fprintf(stderr, "ERROR: version \"%s\" not recognised.\n",
|
||||
argv[i]);
|
||||
xpidl_usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'I':
|
||||
if (argv[i][2] == '\0' && i == argc) {
|
||||
fputs("ERROR: missing path after -I\n", stderr);
|
||||
|
@ -170,7 +228,7 @@ int main(int argc, char *argv[])
|
|||
explicit_output_filename = TRUE;
|
||||
break;
|
||||
case 'm':
|
||||
if (i == argc) {
|
||||
if (i + 1 == argc) {
|
||||
fprintf(stderr, "ERROR: missing modename after -m\n");
|
||||
xpidl_usage(argc, argv);
|
||||
return 1;
|
||||
|
@ -189,8 +247,7 @@ int main(int argc, char *argv[])
|
|||
xpidl_usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown option %s\n", argv[i]);
|
||||
xpidl_usage(argc, argv);
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
#include <IDL.h>
|
||||
#endif
|
||||
|
||||
#include <xpt_struct.h>
|
||||
|
||||
/*
|
||||
* IDL_tree_warning bombs on libIDL version 6.5, and I don't want to not write
|
||||
* warnings... so I define a versioned one here. Thanks to Mike Shaver for the
|
||||
|
@ -84,6 +86,9 @@ extern gboolean verbose_mode;
|
|||
extern gboolean emit_typelib_annotations;
|
||||
extern gboolean explicit_output_filename;
|
||||
|
||||
extern PRUint8 major_version;
|
||||
extern PRUint8 minor_version;
|
||||
|
||||
typedef struct TreeState TreeState;
|
||||
|
||||
/*
|
||||
|
@ -178,7 +183,6 @@ xpidl_write_comment(TreeState *state, int indent);
|
|||
/*
|
||||
* Functions for parsing and printing UUIDs.
|
||||
*/
|
||||
#include <xpt_struct.h>
|
||||
|
||||
/*
|
||||
* How large should the buffer supplied to xpidl_sprint_IID be?
|
||||
|
@ -219,7 +223,10 @@ xpidl_parse_iid(nsID *id, const char *str);
|
|||
UP_IS_AGGREGATE(node)))
|
||||
|
||||
#define DIPPER_TYPE(node) \
|
||||
(NULL != IDL_tree_property_get(node, "domstring"))
|
||||
(NULL != IDL_tree_property_get(node, "domstring") || \
|
||||
NULL != IDL_tree_property_get(node, "utf8string") || \
|
||||
NULL != IDL_tree_property_get(node, "cstring") || \
|
||||
NULL != IDL_tree_property_get(node, "astring"))
|
||||
|
||||
/*
|
||||
* Find the underlying type of an identifier typedef. Returns NULL
|
||||
|
|
|
@ -682,8 +682,13 @@ write_type(IDL_tree type_tree, gboolean is_out, FILE *outfile)
|
|||
break;
|
||||
case IDLN_IDENT:
|
||||
if (UP_IS_NATIVE(type_tree)) {
|
||||
if (IDL_tree_property_get(type_tree, "domstring")) {
|
||||
if (IDL_tree_property_get(type_tree, "domstring") ||
|
||||
IDL_tree_property_get(type_tree, "astring")) {
|
||||
fputs("nsAString", outfile);
|
||||
} else if (IDL_tree_property_get(type_tree, "utf8string")) {
|
||||
fputs("nsACString", outfile);
|
||||
} else if (IDL_tree_property_get(type_tree, "cstring")) {
|
||||
fputs("nsACString", outfile);
|
||||
} else {
|
||||
fputs(IDL_NATIVE(IDL_NODE_UP(type_tree)).user_type, outfile);
|
||||
}
|
||||
|
@ -740,13 +745,17 @@ write_attr_accessor(IDL_tree attr_tree, FILE * outfile,
|
|||
getter ? 'G' : 'S',
|
||||
toupper(*attrname), attrname + 1);
|
||||
if (mode == AS_DECL || mode == AS_IMPL) {
|
||||
/* Setters for string, wstring, nsid, and domstring get const.
|
||||
/* Setters for string, wstring, nsid, domstring, utf8string,
|
||||
* cstring and astring get const.
|
||||
*/
|
||||
if (!getter &&
|
||||
(IDL_NODE_TYPE(ATTR_TYPE_DECL(attr_tree)) == IDLN_TYPE_STRING ||
|
||||
IDL_NODE_TYPE(ATTR_TYPE_DECL(attr_tree)) == IDLN_TYPE_WIDE_STRING ||
|
||||
IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "nsid") ||
|
||||
IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "domstring")))
|
||||
IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "domstring") ||
|
||||
IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "utf8string") ||
|
||||
IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "cstring") ||
|
||||
IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "astring")))
|
||||
{
|
||||
fputs("const ", outfile);
|
||||
}
|
||||
|
@ -911,8 +920,8 @@ write_param(IDL_tree param_tree, FILE *outfile)
|
|||
{
|
||||
IDL_tree param_type_spec = IDL_PARAM_DCL(param_tree).param_type_spec;
|
||||
gboolean is_in = IDL_PARAM_DCL(param_tree).attr == IDL_PARAM_IN;
|
||||
/* in string, wstring, nsid, domstring, and any
|
||||
* explicitly marked [const] are const
|
||||
/* in string, wstring, nsid, domstring, utf8string, cstring and
|
||||
* astring any explicitly marked [const] are const
|
||||
*/
|
||||
|
||||
if (is_in &&
|
||||
|
@ -921,7 +930,10 @@ write_param(IDL_tree param_tree, FILE *outfile)
|
|||
IDL_tree_property_get(IDL_PARAM_DCL(param_tree).simple_declarator,
|
||||
"const") ||
|
||||
IDL_tree_property_get(param_type_spec, "nsid") ||
|
||||
IDL_tree_property_get(param_type_spec, "domstring"))) {
|
||||
IDL_tree_property_get(param_type_spec, "domstring") ||
|
||||
IDL_tree_property_get(param_type_spec, "utf8string") ||
|
||||
IDL_tree_property_get(param_type_spec, "cstring") ||
|
||||
IDL_tree_property_get(param_type_spec, "astring"))) {
|
||||
fputs("const ", outfile);
|
||||
}
|
||||
else if (IDL_PARAM_DCL(param_tree).attr == IDL_PARAM_OUT &&
|
||||
|
|
|
@ -371,7 +371,8 @@ typelib_prolog(TreeState *state)
|
|||
/* find all interfaces, top-level and referenced by others */
|
||||
IDL_tree_walk_in_order(state->tree, find_interfaces, state);
|
||||
ARENA(state) = XPT_NewArena(1024, sizeof(double), "main xpidl arena");
|
||||
HEADER(state) = XPT_NewHeader(ARENA(state), IFACES(state));
|
||||
HEADER(state) = XPT_NewHeader(ARENA(state), IFACES(state),
|
||||
major_version, minor_version);
|
||||
|
||||
/* fill IDEs from hash table */
|
||||
IFACES(state) = 0;
|
||||
|
@ -861,6 +862,18 @@ handle_iid_is:
|
|||
td->prefix.flags = TD_DOMSTRING | XPT_TDP_POINTER;
|
||||
if (IDL_tree_property_get(type, "ref"))
|
||||
td->prefix.flags |= XPT_TDP_REFERENCE;
|
||||
} else if (IDL_tree_property_get(type, "astring")) {
|
||||
td->prefix.flags = TD_ASTRING | XPT_TDP_POINTER;
|
||||
if (IDL_tree_property_get(type, "ref"))
|
||||
td->prefix.flags |= XPT_TDP_REFERENCE;
|
||||
} else if (IDL_tree_property_get(type, "utf8string")) {
|
||||
td->prefix.flags = TD_UTF8STRING | XPT_TDP_POINTER;
|
||||
if (IDL_tree_property_get(type, "ref"))
|
||||
td->prefix.flags |= XPT_TDP_REFERENCE;
|
||||
} else if (IDL_tree_property_get(type, "cstring")) {
|
||||
td->prefix.flags = TD_CSTRING | XPT_TDP_POINTER;
|
||||
if (IDL_tree_property_get(type, "ref"))
|
||||
td->prefix.flags |= XPT_TDP_REFERENCE;
|
||||
} else {
|
||||
td->prefix.flags = TD_VOID | XPT_TDP_POINTER;
|
||||
}
|
||||
|
|
|
@ -220,6 +220,32 @@ verify_const_declaration(IDL_tree const_tree) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This method consolidates error checking needed when coercing the XPIDL compiler
|
||||
* via the -t flag to generate output for a specific version of XPConnect.
|
||||
*/
|
||||
static gboolean
|
||||
verify_type_fits_version(IDL_tree in_tree, IDL_tree error_tree)
|
||||
{
|
||||
if (major_version == 1 && minor_version == 1)
|
||||
{
|
||||
/* XPIDL Version 1.1 checks */
|
||||
|
||||
/* utf8string, cstring, and astring types are not supported */
|
||||
if (IDL_tree_property_get(in_tree, "utf8string") != NULL ||
|
||||
IDL_tree_property_get(in_tree, "cstring") != NULL ||
|
||||
IDL_tree_property_get(in_tree, "astring") != NULL)
|
||||
{
|
||||
IDL_tree_error(error_tree,
|
||||
"Cannot use [utf8string], [cstring] and [astring] "
|
||||
"types when generating version 1.1 typelibs\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
verify_attribute_declaration(IDL_tree attr_tree)
|
||||
{
|
||||
|
@ -274,8 +300,8 @@ verify_attribute_declaration(IDL_tree attr_tree)
|
|||
return TRUE;
|
||||
|
||||
/*
|
||||
* If it should be scriptable, check that the type is non-native. nsid and
|
||||
* domstring are exempted.
|
||||
* If it should be scriptable, check that the type is non-native. nsid,
|
||||
* domstring, utf8string, cstring, astring are exempted.
|
||||
*/
|
||||
attr_type = IDL_ATTR_DCL(attr_tree).param_type_spec;
|
||||
|
||||
|
@ -283,7 +309,10 @@ verify_attribute_declaration(IDL_tree attr_tree)
|
|||
{
|
||||
if (UP_IS_NATIVE(attr_type) &&
|
||||
IDL_tree_property_get(attr_type, "nsid") == NULL &&
|
||||
IDL_tree_property_get(attr_type, "domstring") == NULL)
|
||||
IDL_tree_property_get(attr_type, "domstring") == NULL &&
|
||||
IDL_tree_property_get(attr_type, "utf8string") == NULL &&
|
||||
IDL_tree_property_get(attr_type, "cstring") == NULL &&
|
||||
IDL_tree_property_get(attr_type, "astring") == NULL)
|
||||
{
|
||||
IDL_tree_error(attr_tree,
|
||||
"attributes in [scriptable] interfaces that are "
|
||||
|
@ -310,6 +339,14 @@ verify_attribute_declaration(IDL_tree attr_tree)
|
|||
"and must be read-only\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run additional error checks on the attribute type if targetting an
|
||||
* older version of XPConnect.
|
||||
*/
|
||||
|
||||
if (!verify_type_fits_version(attr_type, attr_tree))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).next != NULL)
|
||||
|
@ -528,13 +565,17 @@ verify_method_declaration(IDL_tree method_tree)
|
|||
|
||||
/*
|
||||
* Reject this method if it should be scriptable and some parameter is
|
||||
* native that isn't marked with either nsid, domstring, or iid_is.
|
||||
* native that isn't marked with either nsid, domstring, utf8string,
|
||||
* cstring, astring or iid_is.
|
||||
*/
|
||||
if (scriptable_method &&
|
||||
UP_IS_NATIVE(param_type) &&
|
||||
IDL_tree_property_get(param_type, "nsid") == NULL &&
|
||||
IDL_tree_property_get(simple_decl, "iid_is") == NULL &&
|
||||
IDL_tree_property_get(param_type, "domstring") == NULL)
|
||||
IDL_tree_property_get(param_type, "domstring") == NULL &&
|
||||
IDL_tree_property_get(param_type, "utf8string") == NULL &&
|
||||
IDL_tree_property_get(param_type, "cstring") == NULL &&
|
||||
IDL_tree_property_get(param_type, "astring") == NULL)
|
||||
{
|
||||
IDL_tree_error(method_tree,
|
||||
"methods in [scriptable] interfaces that are "
|
||||
|
@ -589,7 +630,7 @@ verify_method_declaration(IDL_tree method_tree)
|
|||
|
||||
/*
|
||||
* Confirm that [shared] attributes are only used with string, wstring,
|
||||
* or native (but not nsid or domstring)
|
||||
* or native (but not nsid, domstring, utf8string, cstring or astring)
|
||||
* and can't be used with [array].
|
||||
*/
|
||||
if (IDL_tree_property_get(simple_decl, "shared") != NULL) {
|
||||
|
@ -608,7 +649,10 @@ verify_method_declaration(IDL_tree method_tree)
|
|||
IDL_NODE_TYPE(real_type) == IDLN_TYPE_WIDE_STRING ||
|
||||
(UP_IS_NATIVE(real_type) &&
|
||||
!IDL_tree_property_get(real_type, "nsid") &&
|
||||
!IDL_tree_property_get(real_type, "domstring"))))
|
||||
!IDL_tree_property_get(real_type, "domstring") &&
|
||||
!IDL_tree_property_get(real_type, "utf8string") &&
|
||||
!IDL_tree_property_get(real_type, "cstring") &&
|
||||
!IDL_tree_property_get(real_type, "astring"))))
|
||||
{
|
||||
IDL_tree_error(method_tree,
|
||||
"[shared] parameter \"%s\" must be of type "
|
||||
|
@ -618,27 +662,34 @@ verify_method_declaration(IDL_tree method_tree)
|
|||
}
|
||||
|
||||
/*
|
||||
* inout is not allowed with "domstring" types
|
||||
* inout is not allowed with "domstring", "UTF8String", "CString"
|
||||
* and "AString" types
|
||||
*/
|
||||
if (IDL_PARAM_DCL(param).attr == IDL_PARAM_INOUT &&
|
||||
UP_IS_NATIVE(param_type) &&
|
||||
IDL_tree_property_get(param_type, "domstring") != NULL) {
|
||||
(IDL_tree_property_get(param_type, "domstring") != NULL ||
|
||||
IDL_tree_property_get(param_type, "utf8string") != NULL ||
|
||||
IDL_tree_property_get(param_type, "cstring") != NULL ||
|
||||
IDL_tree_property_get(param_type, "astring") != NULL )) {
|
||||
IDL_tree_error(method_tree,
|
||||
"[domstring] types cannot be used as inout "
|
||||
"parameters");
|
||||
"[domstring], [utf8string], [cstring], [astring] "
|
||||
"types cannot be used as inout parameters");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* arrays of "domstring" types not allowed
|
||||
* arrays of domstring, utf8string, cstring, astring types not allowed
|
||||
*/
|
||||
if (IDL_tree_property_get(simple_decl, "array") != NULL &&
|
||||
UP_IS_NATIVE(param_type) &&
|
||||
IDL_tree_property_get(param_type, "domstring") != NULL) {
|
||||
(IDL_tree_property_get(param_type, "domstring") != NULL ||
|
||||
IDL_tree_property_get(param_type, "utf8string") != NULL ||
|
||||
IDL_tree_property_get(param_type, "cstring") != NULL ||
|
||||
IDL_tree_property_get(param_type, "astring") != NULL)) {
|
||||
IDL_tree_error(method_tree,
|
||||
"[domstring] types cannot be used in array "
|
||||
"parameters");
|
||||
"[domstring], [utf8string], [cstring], [astring] "
|
||||
"types cannot be used in array parameters");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -646,6 +697,15 @@ verify_method_declaration(IDL_tree method_tree)
|
|||
!check_param_attribute(method_tree, param, LENGTH_IS) ||
|
||||
!check_param_attribute(method_tree, param, SIZE_IS))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Run additional error checks on the parameter type if targetting an
|
||||
* older version of XPConnect.
|
||||
*/
|
||||
|
||||
if (!verify_type_fits_version(param_type, method_tree))
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
/* XXX q: can return type be nsid? */
|
||||
|
@ -653,7 +713,10 @@ verify_method_declaration(IDL_tree method_tree)
|
|||
if (scriptable_method &&
|
||||
op->op_type_spec != NULL && UP_IS_NATIVE(op->op_type_spec) &&
|
||||
IDL_tree_property_get(op->op_type_spec, "nsid") == NULL &&
|
||||
IDL_tree_property_get(op->op_type_spec, "domstring") == NULL)
|
||||
IDL_tree_property_get(op->op_type_spec, "domstring") == NULL &&
|
||||
IDL_tree_property_get(op->op_type_spec, "utf8string") == NULL &&
|
||||
IDL_tree_property_get(op->op_type_spec, "cstring") == NULL &&
|
||||
IDL_tree_property_get(op->op_type_spec, "astring") == NULL)
|
||||
{
|
||||
IDL_tree_error(method_tree,
|
||||
"methods in [scriptable] interfaces that are "
|
||||
|
@ -662,6 +725,7 @@ verify_method_declaration(IDL_tree method_tree)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nsid's parameters that aren't ptr's or ref's are not currently
|
||||
* supported in xpcom
|
||||
|
@ -681,6 +745,17 @@ verify_method_declaration(IDL_tree method_tree)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run additional error checks on the return type if targetting an
|
||||
* older version of XPConnect.
|
||||
*/
|
||||
|
||||
if (op->op_type_spec != NULL &&
|
||||
!verify_type_fits_version(op->op_type_spec, method_tree))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ struct XPTHeader {
|
|||
/* For error messages. */
|
||||
#define XPT_MAGIC_STRING "XPCOM\\nTypeLib\\r\\n\\032"
|
||||
#define XPT_MAJOR_VERSION 0x01
|
||||
#define XPT_MINOR_VERSION 0x01
|
||||
#define XPT_MINOR_VERSION 0x02
|
||||
|
||||
/* Any file with a major version number of XPT_MAJOR_INCOMPATIBLE_VERSION
|
||||
* or higher is to be considered incompatible by this version of xpt and
|
||||
|
@ -130,9 +130,66 @@ struct XPTHeader {
|
|||
*/
|
||||
#define XPT_MAJOR_INCOMPATIBLE_VERSION 0x02
|
||||
|
||||
/*
|
||||
* The "[-t version number]" cmd line parameter to the XPIDL compiler and XPT
|
||||
* linker specifies the major and minor version number of the output
|
||||
* type library.
|
||||
*
|
||||
* The goal is for the compiler to check that the input IDL file only uses
|
||||
* constructs that are supported in the version specified. The linker will
|
||||
* check that all typelib files it reads are of the version specified or
|
||||
* below.
|
||||
*
|
||||
* Both the compiler and the linker will report errors and abort if these
|
||||
* checks fail.
|
||||
*
|
||||
* When you rev up major or minor versions of the type library in the future,
|
||||
* think about the new stuff that you added to the type library and add checks
|
||||
* to make sure that occurrences of that new "stuff" will get caught when [-t
|
||||
* version number] is used with the compiler. Here's what you'll probably
|
||||
* have to do each time you rev up major/minor versions:
|
||||
*
|
||||
* 1) Add the current version number string (before your change) to the
|
||||
* XPT_TYPELIB_VERSIONS list.
|
||||
*
|
||||
* 2) Do your changes add new features to XPIDL? Ensure that those new
|
||||
* features are rejected by the XPIDL compiler when any version number in
|
||||
* the XPT_TYPELIB_VERSIONS list is specified on the command line. The
|
||||
* one place that currently does this kind of error checking is the function
|
||||
* verify_type_fits_version() in xpidl_util.c. It currently checks
|
||||
* attribute types, parameter types, and return types. You'll probably have
|
||||
* to add to it or generalize it further based on what kind of changes you
|
||||
* are making.
|
||||
*
|
||||
* 3) You will probably NOT need to make any changes to the error checking
|
||||
* in the linker.
|
||||
*/
|
||||
|
||||
#define XPT_VERSION_UNKNOWN 0
|
||||
#define XPT_VERSION_UNSUPPORTED 1
|
||||
#define XPT_VERSION_OLD 2
|
||||
#define XPT_VERSION_CURRENT 3
|
||||
|
||||
typedef struct {
|
||||
const char* str;
|
||||
PRUint8 major;
|
||||
PRUint8 minor;
|
||||
PRUint16 code;
|
||||
} XPT_TYPELIB_VERSIONS_STRUCT;
|
||||
|
||||
/* Currently accepted list of versions for typelibs */
|
||||
#define XPT_TYPELIB_VERSIONS { \
|
||||
{"1.0", 1, 0, XPT_VERSION_UNSUPPORTED}, \
|
||||
{"1.1", 1, 1, XPT_VERSION_OLD}, \
|
||||
{"1.2", 1, 2, XPT_VERSION_CURRENT} \
|
||||
};
|
||||
|
||||
extern XPT_PUBLIC_API(PRUint16)
|
||||
XPT_ParseVersionString(const char* str, PRUint8* major, PRUint8* minor);
|
||||
|
||||
extern XPT_PUBLIC_API(XPTHeader *)
|
||||
XPT_NewHeader(XPTArena *arena, PRUint16 num_interfaces);
|
||||
XPT_NewHeader(XPTArena *arena, PRUint16 num_interfaces,
|
||||
PRUint8 major_version, PRUint8 minor_version);
|
||||
|
||||
extern XPT_PUBLIC_API(void)
|
||||
XPT_FreeHeader(XPTArena *arena, XPTHeader* aHeader);
|
||||
|
@ -315,7 +372,10 @@ enum XPTTypeDescriptorTags {
|
|||
TD_INTERFACE_IS_TYPE = 19,
|
||||
TD_ARRAY = 20,
|
||||
TD_PSTRING_SIZE_IS = 21,
|
||||
TD_PWSTRING_SIZE_IS = 22
|
||||
TD_PWSTRING_SIZE_IS = 22,
|
||||
TD_UTF8STRING = 23,
|
||||
TD_CSTRING = 24,
|
||||
TD_ASTRING = 25,
|
||||
};
|
||||
|
||||
struct XPTTypeDescriptor {
|
||||
|
|
|
@ -120,14 +120,14 @@ XPT_SizeOfHeaderBlock(XPTHeader *header)
|
|||
}
|
||||
|
||||
XPT_PUBLIC_API(XPTHeader *)
|
||||
XPT_NewHeader(XPTArena *arena, PRUint16 num_interfaces)
|
||||
XPT_NewHeader(XPTArena *arena, PRUint16 num_interfaces, PRUint8 major_version, PRUint8 minor_version)
|
||||
{
|
||||
XPTHeader *header = XPT_NEWZAP(arena, XPTHeader);
|
||||
if (!header)
|
||||
return NULL;
|
||||
memcpy(header->magic, XPT_MAGIC, 16);
|
||||
header->major_version = XPT_MAJOR_VERSION;
|
||||
header->minor_version = XPT_MINOR_VERSION;
|
||||
header->major_version = major_version;
|
||||
header->minor_version = minor_version;
|
||||
header->num_interfaces = num_interfaces;
|
||||
if (num_interfaces) {
|
||||
header->interface_directory =
|
||||
|
@ -936,3 +936,21 @@ XPT_GetInterfaceIndexByName(XPTInterfaceDirectoryEntry *ide_block,
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static XPT_TYPELIB_VERSIONS_STRUCT versions[] = XPT_TYPELIB_VERSIONS;
|
||||
#define XPT_TYPELIB_VERSIONS_COUNT (sizeof(versions) / sizeof(versions[0]))
|
||||
|
||||
XPT_PUBLIC_API(PRUint16)
|
||||
XPT_ParseVersionString(const char* str, PRUint8* major, PRUint8* minor)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < XPT_TYPELIB_VERSIONS_COUNT; i++) {
|
||||
if (!strcmp(versions[i].str, str)) {
|
||||
*major = versions[i].major;
|
||||
*minor = versions[i].minor;
|
||||
return versions[i].code;
|
||||
}
|
||||
}
|
||||
return XPT_VERSION_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ main(int argc, char **argv)
|
|||
TRY("XPT_NewArena", arena);
|
||||
|
||||
/* construct a header */
|
||||
header = XPT_NewHeader(arena, 1);
|
||||
header = XPT_NewHeader(arena, 1, XPT_MAJOR_VERSION, XPT_MINOR_VERSION);
|
||||
TRY("NewHeader", header);
|
||||
|
||||
|
||||
|
|
|
@ -73,8 +73,8 @@ static char *ptype_array[32] =
|
|||
"float *", "double *", "boolean *", "char *",
|
||||
"wchar_t *", "void *", "nsIID *", "DOMString *",
|
||||
"string", "wstring", "Interface *", "InterfaceIs *",
|
||||
"array", "string_s", "wstring_s", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved",
|
||||
"array", "string_s", "wstring_s", "UTF8String *",
|
||||
"CString *", "AString *", "reserved", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved"};
|
||||
|
||||
static char *rtype_array[32] =
|
||||
|
@ -83,8 +83,8 @@ static char *rtype_array[32] =
|
|||
"float &", "double &", "boolean &", "char &",
|
||||
"wchar_t &", "void &", "nsIID &", "DOMString &",
|
||||
"string &", "wstring &", "Interface &", "InterfaceIs &",
|
||||
"array &", "string_s &", "wstring_s &", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved",
|
||||
"array &", "string_s &", "wstring_s &", "UTF8String &",
|
||||
"CString &", "AString &", "reserved", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved"};
|
||||
|
||||
PRBool param_problems = PR_FALSE;
|
||||
|
|
|
@ -95,6 +95,10 @@ PRUint16 trueNumberOfInterfaces = 0;
|
|||
PRUint16 totalNumberOfInterfaces = 0;
|
||||
PRUint16 oldTotalNumberOfInterfaces = 0;
|
||||
|
||||
/* The following globals are explained in xpt_struct.h */
|
||||
PRUint8 major_version = XPT_MAJOR_VERSION;
|
||||
PRUint8 minor_version = XPT_MINOR_VERSION;
|
||||
|
||||
#if defined(XP_MAC) && defined(XPIDL_PLUGIN)
|
||||
|
||||
#define main xptlink_main
|
||||
|
@ -132,6 +136,7 @@ main(int argc, char **argv)
|
|||
PRUint32 newOffset;
|
||||
size_t flen = 0;
|
||||
char *head, *data, *whole;
|
||||
const char *outFileName;
|
||||
FILE *in, *out;
|
||||
fixElement *fix_array = NULL;
|
||||
int i,j;
|
||||
|
@ -150,7 +155,54 @@ main(int argc, char **argv)
|
|||
|
||||
first_ann = XPT_NewAnnotation(arena, XPT_ANN_LAST, NULL, NULL);
|
||||
|
||||
for (i=2; i<argc; i++) {
|
||||
/* Check if the "-t version numnber" cmd line arg is present */
|
||||
i = 1;
|
||||
if (argv[i][0] == '-' && argv[i][1] == 't') {
|
||||
/* Parse for "-t version number" */
|
||||
|
||||
/* If -t is the last argument on the command line, we have a problem */
|
||||
if (i + 1 == argc) {
|
||||
fprintf(stderr, "ERROR: missing version number after -t\n");
|
||||
xpt_link_usage(argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that the argument after "-t" is the version number string
|
||||
* and search for it in our internal list of acceptable version
|
||||
* numbers.
|
||||
*/
|
||||
|
||||
switch (XPT_ParseVersionString(argv[++i], &major_version,
|
||||
&minor_version)) {
|
||||
case XPT_VERSION_CURRENT:
|
||||
case XPT_VERSION_OLD:
|
||||
break;
|
||||
case XPT_VERSION_UNSUPPORTED:
|
||||
fprintf(stderr, "ERROR: version \"%s\" not supported.\n",
|
||||
argv[i]);
|
||||
xpt_link_usage(argv);
|
||||
return 1;
|
||||
case XPT_VERSION_UNKNOWN:
|
||||
default:
|
||||
fprintf(stderr, "ERROR: version \"%s\" not recognised.\n",
|
||||
argv[i]);
|
||||
xpt_link_usage(argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Hang onto the output file name. It's needed later. */
|
||||
outFileName = argv[++i];
|
||||
|
||||
/* Increment i to the cmd line arg after outFileName */
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
outFileName = argv[1];
|
||||
i = 2;
|
||||
}
|
||||
|
||||
for ( /* use i from earlier */ ; i < argc; i++) {
|
||||
char *name = argv[i];
|
||||
|
||||
flen = get_file_length(name);
|
||||
|
@ -192,7 +244,24 @@ main(int argc, char **argv)
|
|||
"DoHeader failed for %s. Is %s a valid .xpt file?\n",
|
||||
name, name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that the version of the typelib file is less than or
|
||||
* equal to the version specified in the -t cmd line arg.
|
||||
*/
|
||||
|
||||
if (header &&
|
||||
(header->major_version > major_version ||
|
||||
(header->major_version == major_version &&
|
||||
header->minor_version > minor_version))) {
|
||||
fprintf(stderr, "FAILED: %s's version, %d.%d, is newer than "
|
||||
"the version (%d.%d) specified in the -t "
|
||||
"command line argument.\n",
|
||||
name, header->major_version, header->minor_version,
|
||||
major_version, minor_version);
|
||||
return 1;
|
||||
}
|
||||
|
||||
oldTotalNumberOfInterfaces = totalNumberOfInterfaces;
|
||||
totalNumberOfInterfaces += header->num_interfaces;
|
||||
|
@ -492,7 +561,9 @@ main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
header = XPT_NewHeader(arena, (PRUint16)trueNumberOfInterfaces);
|
||||
header = XPT_NewHeader(arena, (PRUint16)trueNumberOfInterfaces,
|
||||
major_version, minor_version);
|
||||
|
||||
header->annotations = first_ann;
|
||||
for (i=0; i<trueNumberOfInterfaces; i++) {
|
||||
if (!copy_IDE(&IDE_array[i], &header->interface_directory[i])) {
|
||||
|
@ -531,7 +602,7 @@ main(int argc, char **argv)
|
|||
return 1;
|
||||
}
|
||||
XPT_SeekTo(cursor, newOffset);
|
||||
out = fopen(argv[1], "wb");
|
||||
out = fopen(outFileName, "wb");
|
||||
if (!out) {
|
||||
perror("FAILED: fopen");
|
||||
return 1;
|
||||
|
@ -805,7 +876,8 @@ print_IID(struct nsID *iid, FILE *file)
|
|||
static void
|
||||
xpt_link_usage(char *argv[])
|
||||
{
|
||||
fprintf(stdout, "Usage: %s outfile file1.xpt file2.xpt ...\n"
|
||||
" Links multiple typelib files into one outfile\n", argv[0]);
|
||||
fprintf(stdout, "Usage: %s [-t version number] outfile file1.xpt file2.xpt ...\n"
|
||||
" Links multiple typelib files into one outfile\n"
|
||||
" -t create a typelib of an older version number\n", argv[0]);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче