287 lines
7.7 KiB
C
287 lines
7.7 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Mozilla Communicator client code,
|
|
* released March 31, 1998.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Daniel Veditz <dveditz@netscape.com>
|
|
*/
|
|
|
|
#include "xp.h"
|
|
#include "jsapi.h"
|
|
#include "prprf.h"
|
|
|
|
#include "su_mocha.h"
|
|
#include "softupdt.h"
|
|
|
|
|
|
|
|
/* prototypes */
|
|
|
|
static JSBool PR_CALLBACK NewVersion(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval *rval);
|
|
|
|
static JSBool PR_CALLBACK su_versionCompareTo(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval *rval);
|
|
static JSBool PR_CALLBACK su_verobjToString(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval *rval);
|
|
|
|
|
|
|
|
/* structures */
|
|
|
|
char su_major_str[] = "major";
|
|
char su_minor_str[] = "minor";
|
|
char su_release_str[] = "release";
|
|
char su_build_str[] = "build";
|
|
|
|
JSClass su_version_class = {
|
|
"InstallVersion",
|
|
0,
|
|
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
|
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
|
};
|
|
|
|
static JSFunctionSpec version_methods[] = {
|
|
{"compareTo", su_versionCompareTo, 1},
|
|
{"toString", su_verobjToString, 0},
|
|
{0}
|
|
};
|
|
|
|
static JSConstDoubleSpec version_constants[] = {
|
|
{ SU_EQUAL, su_equal_str },
|
|
{ SU_BLD_DIFF, su_bldDiff_str },
|
|
{ SU_REL_DIFF, su_relDiff_str },
|
|
{ SU_MINOR_DIFF, su_minorDiff_str },
|
|
{ SU_MAJOR_DIFF, su_majorDiff_str },
|
|
{0}
|
|
};
|
|
|
|
|
|
|
|
/* implementations */
|
|
|
|
/**
|
|
* adds the InstallVersion class to a JS context
|
|
*/
|
|
JSBool su_DefineVersion(JSContext *cx, JSObject *obj)
|
|
{
|
|
JSObject *su_version_proto;
|
|
|
|
su_version_proto = JS_InitClass(cx, obj, NULL, &su_version_class, NewVersion, 1,
|
|
NULL, version_methods, NULL, NULL);
|
|
|
|
if ( su_version_proto != NULL )
|
|
if ( JS_DefineConstDoubles(cx, su_version_proto, version_constants) )
|
|
return JS_TRUE;
|
|
|
|
return JS_FALSE;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* InstallVersion constructor
|
|
*/
|
|
static JSBool PR_CALLBACK NewVersion(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval *rval)
|
|
{
|
|
VERSION vers;
|
|
|
|
if ( argc > 0 && JSVAL_IS_STRING(argv[0]) ) {
|
|
su_strToVersion( JS_GetStringBytes(JSVAL_TO_STRING(argv[0])), &vers );
|
|
}
|
|
else {
|
|
vers.major = vers.minor = vers.release = vers.build = 0;
|
|
|
|
if ( argc > 0 && JSVAL_IS_INT(argv[0]) )
|
|
vers.major = JSVAL_TO_INT(argv[0]);
|
|
|
|
if ( argc > 1 && JSVAL_IS_INT(argv[1]) )
|
|
vers.minor = JSVAL_TO_INT(argv[1]);
|
|
|
|
if ( argc > 2 && JSVAL_IS_INT(argv[2]) )
|
|
vers.release = JSVAL_TO_INT(argv[2]);
|
|
|
|
if ( argc > 3 && JSVAL_IS_INT(argv[3]) )
|
|
vers.build = JSVAL_TO_INT(argv[3]);
|
|
}
|
|
|
|
su_versToObj(cx, &vers, obj);
|
|
return JS_TRUE;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* implementation of InstallVersion.compareTo()
|
|
*/
|
|
static JSBool PR_CALLBACK su_versionCompareTo(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval *rval)
|
|
{
|
|
int compval;
|
|
VERSION thisver, v;
|
|
|
|
if ( argc == 0 )
|
|
return JS_FALSE;
|
|
|
|
if ( JSVAL_IS_STRING(argv[0]) ) {
|
|
su_strToVersion( JS_GetStringBytes(JSVAL_TO_STRING(argv[0])), &v );
|
|
}
|
|
else if (JSVAL_IS_OBJECT(argv[0]) ) {
|
|
/* check to make sure it's an InstallVersion */
|
|
JSObject *argobj;
|
|
JSClass *argclass;
|
|
|
|
argobj = JSVAL_TO_OBJECT(argv[0]);
|
|
argclass = JS_GetClass(cx, argobj);
|
|
|
|
if ( argclass != &su_version_class ) {
|
|
/* XXX report error here */
|
|
return JS_FALSE;
|
|
}
|
|
|
|
su_objToVers( cx, argobj, &v );
|
|
}
|
|
else {
|
|
v.major = v.minor = v.release = v.build = 0;
|
|
|
|
if ( argc > 0 && JSVAL_IS_INT(argv[0]) )
|
|
v.major = JSVAL_TO_INT(argv[0]);
|
|
|
|
if ( argc > 1 && JSVAL_IS_INT(argv[1]) )
|
|
v.minor = JSVAL_TO_INT(argv[1]);
|
|
|
|
if ( argc > 2 && JSVAL_IS_INT(argv[2]) )
|
|
v.release = JSVAL_TO_INT(argv[2]);
|
|
|
|
if ( argc > 3 && JSVAL_IS_INT(argv[3]) )
|
|
v.build = JSVAL_TO_INT(argv[3]);
|
|
}
|
|
|
|
su_objToVers( cx, obj, &thisver );
|
|
|
|
compval = su_compareVersions( &thisver, &v );
|
|
*rval = INT_TO_JSVAL(compval);
|
|
|
|
return JS_TRUE;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* implementation of InstallVersion.toString()
|
|
*/
|
|
static JSBool PR_CALLBACK su_verobjToString(JSContext *cx, JSObject *obj, uint argc, jsval *argv, jsval *rval)
|
|
{
|
|
char *str;
|
|
VERSION v;
|
|
|
|
su_objToVers(cx, obj, &v );
|
|
|
|
str = PR_smprintf("%d.%d.%d.%d", v.major, v.minor, v.release, v.build);
|
|
|
|
*rval = STRING_TO_JSVAL( JS_NewStringCopyZ(cx,str) );
|
|
|
|
PR_smprintf_free(str);
|
|
return JS_TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Convert VERSION type to Version JS object */
|
|
void su_versToObj(JSContext *cx, VERSION* vers, JSObject* versObj)
|
|
{
|
|
jsval val = INT_TO_JSVAL(vers->major);
|
|
JS_SetProperty(cx, versObj, su_major_str, &val);
|
|
val = INT_TO_JSVAL(vers->minor);
|
|
JS_SetProperty(cx, versObj, su_minor_str, &val);
|
|
val = INT_TO_JSVAL(vers->release);
|
|
JS_SetProperty(cx, versObj, su_release_str, &val);
|
|
val = INT_TO_JSVAL(vers->build);
|
|
JS_SetProperty(cx, versObj, su_build_str, &val);
|
|
}
|
|
|
|
/* Convert Version JS object to VERSION type */
|
|
void su_objToVers(JSContext *cx, JSObject* versObj, VERSION* vers)
|
|
{
|
|
jsval val;
|
|
JS_GetProperty(cx, versObj, su_major_str, &val);
|
|
vers->major = JSVAL_TO_INT(val);
|
|
JS_GetProperty(cx, versObj, su_minor_str, &val);
|
|
vers->minor = JSVAL_TO_INT(val);
|
|
JS_GetProperty(cx, versObj, su_release_str, &val);
|
|
vers->release = JSVAL_TO_INT(val);
|
|
JS_GetProperty(cx, versObj, su_build_str, &val);
|
|
vers->build = JSVAL_TO_INT(val);
|
|
}
|
|
|
|
/* Convert version string ("4.1.0.8743") to VERSION type */
|
|
void su_strToVersion(char * verstr, VERSION* vers)
|
|
{
|
|
char *p;
|
|
char *o = verstr;
|
|
|
|
vers->major = vers->minor = vers->release = vers->build = 0;
|
|
|
|
if ( o != NULL ) {
|
|
p = strchr(o, '.');
|
|
vers->major = atoi(o);
|
|
|
|
if ( p != NULL ) {
|
|
o = p+1;
|
|
p = strchr(o, '.');
|
|
vers->minor = atoi(o);
|
|
|
|
if ( p != NULL ) {
|
|
o = p+1;
|
|
p = strchr(o,'.');
|
|
vers->release = atoi(o);
|
|
|
|
if ( p != NULL ) {
|
|
o = p+1;
|
|
p = strchr(o,'.');
|
|
vers->build = atoi(o);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns 0 if versions are equal; < 0 if vers1 is older; > 0 if vers1 is newer
|
|
*/
|
|
int su_compareVersions(VERSION* vers1, VERSION* vers2)
|
|
{
|
|
int diff;
|
|
if (vers1 == NULL)
|
|
diff = -SU_MAJOR_DIFF;
|
|
else if (vers2 == NULL)
|
|
diff = SU_MAJOR_DIFF;
|
|
else if (vers1->major == vers2->major) {
|
|
if (vers1->minor == vers2->minor) {
|
|
if (vers1->release == vers2->release) {
|
|
if (vers1->build == vers2->build)
|
|
diff = SU_EQUAL;
|
|
else diff = (vers1->build > vers2->build) ? SU_BLD_DIFF: -SU_BLD_DIFF;
|
|
}
|
|
else diff = (vers1->release > vers2->release) ? SU_REL_DIFF: -SU_REL_DIFF;
|
|
}
|
|
else diff = (vers1->minor > vers2->minor) ? SU_MINOR_DIFF: -SU_MINOR_DIFF;
|
|
}
|
|
else diff = (vers1->major > vers2->major) ? SU_MAJOR_DIFF : -SU_MAJOR_DIFF;
|
|
|
|
return diff;
|
|
}
|