File: [local] / OpenXM / src / kan96xx / plugin / oxmisc2.c (download)
Revision 1.4, Sat Nov 27 01:41:11 1999 UTC (24 years, 10 months ago) by takayama
Branch: MAIN
CVS Tags: RELEASE_20000124 Changes since 1.3: +82 -37
lines
The new mathcap format is supported.
|
/* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc2.c,v 1.4 1999/11/27 01:41:11 takayama Exp $ */
#include <stdio.h>
#include "ox_kan.h"
#include "oxmisc2.h" /* This file requires sm1 object description. */
#include "cmo.h"
extern FILE *MyErrorOut;
extern int SerialOX; /* defined in SerialOX */
extern int OxVersion;
int DebugMathCap = 1;
int oxGet(oxclientp client, struct object *op,int *isObj)
/* This method should be synchronized. */
/* oxGet is a function for client. */
{
int ans;
ox_stream os;
int m;
struct object rob;
int sss; /* Serial number of the recieved packet. */
*isObj = 0;
op->tag = Snull;
os = client->datafp2;
switch(client->dstate) {
case DSTATE_ANY:
m = oxGetOXheader(os,&sss);
switch(m) {
case OX_DATA:
client->dstate = DSTATE_WAIT_OX_DATA;
return(oxGet(client,op,isObj));
case OX_SYNC_BALL:
client->dstate = DSTATE_ANY;
return(OX_SYNC_BALL);
default:
errorOxmisc2("oxGet: cannot handle this tag.\n");
client->dstate = DSTATE_ERROR;
return(-1);
}
break;
case DSTATE_FIRST_SYNC: /* waiting the first sync ball */
/* I need to clear the buffer?? */
oxWaitSyncBall(os);
client->dstate = DSTATE_ANY;
oxSendSyncBall(os);
return(OX_SYNC_BALL);
break;
case DSTATE_WAIT_OX_DATA: /* waiting a cmo data. */
*op = cmoObjectFromStream2(client->datafp2);
client->dstate = DSTATE_ANY;
*isObj = 1;
return(0);
break;
case DSTATE_ERROR:
client->dstate = DSTATE_ERROR;
errorOxmisc2("oxGet: dstate == DSTATE_ERROR (error state)\n");
return(-1);
default:
client->dstate = DSTATE_ERROR;
errorOxmisc2("oxGet: Unknown state number.");
}
return(-1);
}
int oxGetFromControl(oxclientp client)
{
int ans = -1;
if (client->cstate != -1) {
ans = oxGetResultOfControlInt32(client->controlfd);
if (ans != -1) { client->cstate = 0; }
else {client->cstate = -1; }
}
return(ans);
}
int oxReq(oxclientp client,int func,struct object ob)
{
struct object *ob1p;
/* request to the control channel */
if (func == SM_control_reset_connection ||
func == SM_control_kill) {
switch(func) {
case SM_control_reset_connection:
oxReqControlResetConnection(client->controlfd);
client->cstate = 1;
client->dstate = DSTATE_FIRST_SYNC;
break;
case SM_control_kill:
oxReqControlKill(client->controlfd);
client->cstate = 0;
client->dstate = DSTATE_ANY;
break;
}
fflush(NULL);
return(0);
}
/* request to the data channel */
if (client->dstate != DSTATE_ANY) {
errorOxmisc2("oxReq: client->dstate != DSTATE_ANY, data channel is not ready to send data.\n");
return(-1);
}
switch(func) {
case SM_DUMMY_sendcmo:
if (!cmoCheckMathCap(ob,(struct object *)client->mathcapObjp)) {
errorOxmisc2("oxReq: your peer does not understand this cmo.\n");
return(-1);
}
oxSendOXheader(client->datafp2,OX_DATA,SerialOX++);
cmoObjectToStream2(ob,client->datafp2);
client->dstate = DSTATE_ANY;
break;
case SM_sync_ball:
oxSendSyncBall(client->datafp2);
client->dstate = DSTATE_ANY; /* We do not expect the sync ball.*/
client->cstate = 0; /* clear the cstate */
break;
case SM_popCMO:
oxReqPopCMO(client->datafp2);
client->dstate = DSTATE_ANY;
break;
case SM_mathcap:
oxReqMathCap(client->datafp2);
client->dstate = DSTATE_ANY;
break;
case SM_setMathCap:
/* ob = [(mathcap-obj) [[version num, system name] [sm tags]
ob1 smtags
oxtags [[ox numbers, [cmo numbers]]]
ob3 ob2 */
/* oxtags [[OX_DATA, [cmo numbers]],[OX_DATA_LOCAL,[opt]],...]*/
{
struct object ob1;
struct object ob2;
struct object ob3;
struct object obm;
struct object smtags;
struct object oxtags;
struct object ox;
int n,i;
struct mathCap mathcap;
if (strcmp(KopString(getoa(ob,0)),"mathcap-object") != 0) {
errorOxmisc2("data format error in oxReqSetMathCap");
client->dstate = DSTATE_ANY;
break;
}
obm = getoa(ob,1);
ob1 = getoa(obm,0);
smtags = getoa(obm,1);
oxtags = getoa(obm,2);
if (smtags.tag != Sarray || oxtags.tag != Sarray) {
errorOxmisc2("data format error in oxReqSetMathCap");
}
ob1p = (struct object *) sGC_malloc(sizeof(struct object));
*ob1p = ob1;
mathcap.infop = ob1p;
n = getoaSize(oxtags);
if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
mathcap.oxSize = n;
for (i=0; i<n; i++) {
ox = getoa(oxtags,i);
if (ox.tag != Sarray) {
errorOxmisc2("Data format error of the third argument of mathcap.");
}
mathcap.ox[i] = KopInteger(getoa(ox,0));
if (mathcap.ox[i] == OX_DATA) {
if (getoaSize(ox) < 2) {
errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
}
ob2 = getoa(ox,1);
if (ob2.tag != Sarray) {
errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
}
mathcap.n = getoaSize(ob2);
if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
for (i=0; i<mathcap.n; i++) {
mathcap.cmo[i] = KopInteger(getoa(ob2,i));
}
}
}
n = getoaSize(smtags);
if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
mathcap.smSize = n;
for (i=0; i<n; i++) {
mathcap.sm[i] = KopInteger(getoa(smtags,i));
}
oxReqSetMathCap(client->datafp2,&mathcap);
client->dstate = DSTATE_ANY;
}
break;
case SM_pops:
if (ob.tag != Sinteger) {
errorOxmisc2("SM_pops : the argument must be an integer.");
return(-1);
}
oxReqPops(client->datafp2, KopInteger(ob));
client->dstate = DSTATE_ANY;
break;
case SM_executeStringByLocalParser:
if (ob.tag != Sdollar) {
errorOxmisc2("SM_executeStringByLocalParser : the argument must be a string.");
return(-1);
}
oxReqExecuteStringByLocalParser(client->datafp2,KopString(ob));
client->dstate = DSTATE_ANY;
break;
case SM_executeFunction:
if (ob.tag != Sdollar) {
errorOxmisc2("SM_executeFunction : the argument must be a string.");
return(-1);
}
oxReqExecuteFunction(client->datafp2,KopString(ob));
client->dstate = DSTATE_ANY;
break;
case SM_popString:
oxReqPopString(client->datafp2);
client->dstate = DSTATE_ANY;
break;
case SM_evalName:
if (ob.tag != Sdollar) {
errorOxmisc2("SM_evalName : the argument must be a string.");
return(-1);
}
oxReqEvalName(client->datafp2,KopString(ob));
client->dstate = DSTATE_ANY;
break;
case SM_setName:
if (ob.tag != Sdollar) {
errorOxmisc2("SM_setName : the argument must be a string.");
return(-1);
}
oxReqSetName(client->datafp2,KopString(ob));
client->dstate = DSTATE_ANY;
break;
case SM_getsp:
oxReqSingleOperand(client->datafp2,SM_getsp);
client->dstate = DSTATE_ANY;
break;
case SM_dupErrors:
oxReqSingleOperand(client->datafp2,SM_dupErrors);
client->dstate = DSTATE_ANY;
break;
default:
fprintf(MyErrorOut,"func=%d ",func);
errorOxmisc2("This function is not implemented.");
break;
}
fp2fflush(client->datafp2);
return(0);
}
struct object KoxCreateClient(struct object ip,
struct object portStream,
struct object portControl)
{
struct object rob;
oxclientp client;
rob.tag = Snull;
if (ip.tag != Sdollar) {
errorOxmisc2("KoxCreateClient(): The first argument must be a hostname given by a string.");
return(rob);
}
if (portStream.tag == Sdollar) {
client = oxCreateClientFile(KopString(ip),KopString(portStream),
"/dev/null","w");
if (client == NULL) {
errorOxmisc2("KoxCreateClient(): Open error.");
return(rob);
}
rob = newObjectArray(N_OF_CLIENT_FIELDS);
oxClientToObject(client,rob);
return(rob);
}
if (portStream.tag != Sinteger) {
errorOxmisc2("KoxCreateClient(): The second argument must be a port number given in an integer.");
return(rob);
}
if (portControl.tag != Sinteger) {
errorOxmisc2("KoxCreateClient(): The third argument must be a port number given in an integer.");
return(rob);
}
client = oxCreateClient(KopString(ip),KopInteger(portStream),KopInteger(portControl));
if (client == NULL) {
errorOxmisc2("KoxCreateClient(): Open error.");
return(rob);
}
rob = newObjectArray(N_OF_CLIENT_FIELDS);
oxClientToObject(client,rob);
return(rob);
}
static int isItClientObject(struct object ob)
{
int size,i;
struct object ee[N_OF_CLIENT_FIELDS];
if (ob.tag != Sarray) {
return(0);
}
size = getoaSize(ob);
if (size != N_OF_CLIENT_FIELDS) return(0);
for (i=0; i<N_OF_CLIENT_FIELDS; i++) {
ee[i] = getoa(ob,i);
}
if (ee[0].tag != Sdollar) return(0);
if (strcmp(KopString(ee[0]),"client")!=0) return(0);
if (ee[1].tag != Sfile) return(0);
if (strcmp((ee[1]).lc.str,MAGIC2) != 0) return(0);
for (i=2; i<=9; i++) {
if (ee[i].tag != Sinteger) return(0);
}
return(1);
}
struct object KoxIsThereErrorClient(struct object ob)
{
struct object rob;
int ans;
int size;
oxclient cc;
rob.tag = Snull;
if (!isItClientObject(ob)) {
errorOxmisc2("KoxIsThereErrorClient(): the argument must be an array for client object.");
return(rob);
}
if (oxObjectToClient(ob,&cc) == -1) return(KpoInteger(-1));
ans = oxIsThereErrorClient(&cc);
return(KpoInteger(ans));
}
int oxClientToObject(oxclientp client,struct object rob)
{
struct object ob;
if (client == NULL) return;
/* rob = newObjectArray(N_OF_CLIENT_FIELDS); */
if (rob.tag != Sarray) {
errorOxmisc2("oxClientToObject(): the second argument must be an array.");
return(-1);
}
if (getoaSize(rob) != N_OF_CLIENT_FIELDS) {
errorOxmisc2("oxClientToObject(): the second argument must be an array of size N_OF_CLIENT_FIELDS.");
return(-1);
}
ob = KpoString("client");
putoa(rob,0,ob);
ob.tag = Sfile; ob.lc.str = MAGIC2; ob.rc.voidp = (void *)(client->datafp2);
putoa(rob,1,ob);
putoa(rob,2,KpoInteger(client->dataport));
putoa(rob,3,KpoInteger(client->controlfd));
putoa(rob,4,KpoInteger(client->controlport));
putoa(rob,5,KpoInteger(client->dstate));
putoa(rob,6,KpoInteger(client->cstate));
putoa(rob,7,KpoInteger(client->humanio));
putoa(rob,8,KpoInteger(client->id));
putoa(rob,9,KpoInteger(client->type));
if (client->mathcapObjp == NULL) {
putoa(rob,10,NullObject);
}else{
putoa(rob,10,*((struct object *)(client->mathcapObjp)));
}
putoa(rob,11,KpoInteger(client->engineByteOrder));
putoa(rob,12,KpoInteger(client->controlByteOrder));
return(0);
}
int oxObjectToClient(struct object ob,oxclientp cp)
{
struct object ob1;
struct object *obp;
if (cp == NULL) {
errorOxmisc2("oxObjectToClient(): the second argument is NULL");
return(-1);
}
if (!isItClientObject(ob)) {
errorOxmisc2("oxObjectToClient(): the first argument is not client object.");
oxInitClient(cp);
return(-1);
}
ob1 = getoa(ob,1);
cp->datafp2 = (FILE2 *) (ob1.rc.voidp);
ob1 = getoa(ob,2);
cp->dataport = KopInteger(ob1);
ob1 = getoa(ob,3);
cp->controlfd = KopInteger(ob1);
ob1 = getoa(ob,4);
cp->controlport = KopInteger(ob1);
ob1 = getoa(ob,5);
cp->dstate = KopInteger(ob1);
ob1 = getoa(ob,6);
cp->cstate = KopInteger(ob1);
ob1 = getoa(ob,7);
cp->humanio = KopInteger(ob1);
ob1 = getoa(ob,8);
cp->id = KopInteger(ob1);
ob1 = getoa(ob,9);
cp->type = KopInteger(ob1);
ob1 = getoa(ob,10);
if (ob1.tag == Snull) {
cp->mathcapObjp = NULL;
}else{
obp = (struct object *) sGC_malloc(sizeof(struct object));
*obp = ob1;
cp->mathcapObjp = (void *)obp;
}
ob1 = getoa(ob,11);
cp->engineByteOrder = KopInteger(ob1);
ob1 = getoa(ob,12);
cp->controlByteOrder = KopInteger(ob1);
return(0);
}
struct object KoxReq(struct object client,
struct object func,
struct object ob1)
{
int ans;
static oxclientp cc1 = NULL;
struct object rob;
rob.tag = Snull;
if (cc1 == NULL) {
cc1 = (oxclientp) mymalloc(sizeof(oxclient));
if (cc1 == NULL) {
errorOxmisc2("KoxReq(): no more memory.");
return(rob);
}
oxInitClient(cc1);
}
if (oxObjectToClient(client,cc1) == -1) return(rob);
if (cc1 == NULL) {
errorOxmisc2("KoxReq(): the first argument must be a client object.");
return(rob);
}
if (func.tag != Sinteger) {
errorOxmisc2("KoxReq(): the second argument must be an integer.");
return(rob);
}
ans = oxReq(cc1,KopInteger(func),ob1);
/* synchronize cc1 and client. */
oxClientToObject(cc1,client);
return(KpoInteger(ans));
}
struct object KoxGet(struct object client)
{
int ans,k;
static oxclientp cc1 = NULL;
struct object rob;
rob.tag = Snull;
if (cc1 == NULL) {
cc1 = (oxclientp) mymalloc(sizeof(oxclient));
if (cc1 == NULL) {
errorOxmisc2("KoxGet(): no more memory.");
return(rob);
}
oxInitClient(cc1);
}
if (oxObjectToClient(client,cc1) == -1) return(rob);
if (cc1 == NULL) {
errorOxmisc2("KoxGet(): the first argument must be a client object.");
return(rob);
}
ans = oxGet(cc1,&rob,&k);
/* synchronize cc1 and client. */
oxClientToObject(cc1,client);
if (k) return(rob);
else {
return(KpoInteger(ans));
}
}
struct object KoxGetFromControl(struct object client)
{
int ans;
static oxclientp cc1 = NULL;
struct object rob;
rob.tag = Snull;
if (cc1 == NULL) {
cc1 = (oxclientp) mymalloc(sizeof(oxclient));
if (cc1 == NULL) {
errorOxmisc2("KoxGetFromControl(): no more memory.");
return(rob);
}
oxInitClient(cc1);
}
if (oxObjectToClient(client,cc1) == -1) return(rob);
if (cc1 == NULL) {
errorOxmisc2("KoxGetFromControl(): the first argument must be a client object.");
return(rob);
}
ans = oxGetFromControl(cc1);
/* synchronize cc1 and client. */
oxClientToObject(cc1,client);
return(KpoInteger(ans));
}
struct object KoxMultiSelect(struct object oclients,struct object t)
{
static int first = 1;
static int csize = 0;
static oxclientp *clients = NULL;
oxclientp cc1;
struct object rob;
int i;
int tt;
struct object ob1;
struct object ob2;
struct object ob0;
int size;
int ans;
int dataready[1024];
int controlready[1024];
rob.tag = Snull;
if (oclients.tag != Sarray) {
errorOxmisc2("KoxMultiSelect(): the first argument must be an array.");
return(rob);
}
size = getoaSize(oclients);
if (first) {
first = 0; csize = size;
clients = (oxclientp *)mymalloc(sizeof(oxclientp)*(size+1));
if (clients == NULL) {
errorOxmisc2("KoxMultiSelect(): no more memory.");
return(rob);
}
for (i=0; i<size; i++) {
clients[i] = (oxclientp) mymalloc(sizeof(oxclient));
if (clients[i] == NULL) {
errorOxmisc2("KoxMultiSelect(): no more memory.");
return(rob);
}
oxInitClient(clients[i]);
}
}
if (csize < size) {
first = 1;
return(KoxMultiSelect(oclients,t));
}
for (i=0; i<size; i++) {
ob0 = getoa(oclients,i);
if (oxObjectToClient(ob0,clients[i]) == -1) return(rob);
}
if (t.tag != Sinteger) {
errorOxmisc2("KoxMultiSelect(): the second argument must be an integer.");
}
tt = KopInteger(t);
ans = oxclientMultiSelect(clients,dataready,controlready,size,tt);
/* synchronize oclients and clients. */
for (i=0; i<size; i++) {
ob0 = getoa(oclients,i);
oxClientToObject(clients[i],ob0);
putoa(oclients,i,ob0);
}
rob = newObjectArray(3);
putoa(rob,0,KpoInteger(ans));
ob1 = newObjectArray(size);
ob2 = newObjectArray(size);
for (i=0; i<size; i++) {
putoa(ob1,i,KpoInteger(dataready[i]));
putoa(ob2,i,KpoInteger(controlready[i]));
}
putoa(rob,1,ob1);
putoa(rob,2,ob2);
return(rob);
}
struct object KoxWatch(struct object client,struct object f)
/* f is not used for now. It should be log file. */
{
int ans,k;
static oxclientp cc1 = NULL;
struct object rob;
extern int WatchStream;
rob.tag = Snull;
if (client.tag == Sinteger) {
if (KopInteger(client)) {
WatchStream = 1;
}else{
WatchStream = 0;
}
return;
}
if (cc1 == NULL) {
cc1 = (oxclientp) mymalloc(sizeof(oxclient));
if (cc1 == NULL) {
errorOxmisc2("KoxWatch(): no more memory.");
return(rob);
}
oxInitClient(cc1);
}
if (oxObjectToClient(client,cc1) == -1) return(rob);
if (cc1 == NULL) {
errorOxmisc2("KoxWatch(): the first argument must be a client object.");
return(rob);
}
k = fp2watch(cc1->datafp2,stdout);
/* synchronize cc1 and client. */
oxClientToObject(cc1,client);
return(KpoInteger(ans));
}
struct object KoxCloseClient(struct object client) {
oxclientp cc1 = NULL;
oxclient cc;
struct object rob;
rob.tag = Snull;
cc1 = &cc;
if (oxObjectToClient(client,cc1) == -1) return(rob);
if (cc1 == NULL) {
errorOxmisc2("KoxCloseClient(): the first argument must be a client object.");
return(rob);
}
fp2fflush(cc1->datafp2);
if (cc1->humanio) {
/* Do not close the file. */
return(KpoInteger(0));
}
switch (cc1->type) {
case CLIENT_SOCKET:
fp2fclose(cc1->datafp2);
close(cc1->controlfd);
break;
case CLIENT_FILE:
fp2fclose(cc1->datafp2);
close(cc1->controlfd);
break;
default:
errorOxmisc2("Unknown client->type\n");
break;
}
return(KpoInteger(0));
}
static int cmoCheck00(struct object obj,int cmo[], int n) {
int i,j,m;
int ttt;
#define CHECK00_N 4098 /* look up stackm.h and kclass.h */
static int typeTrans[CHECK00_N];
static int init = 0;
if (n == 0) return(1); /* For null cmolist, OK. */
if (!init) {
for (i=0; i<CHECK00_N; i++) {
typeTrans[i] = 0; /* unknown cmo number */
}
typeTrans[Snull] = CMO_NULL;
typeTrans[Sinteger] = CMO_INT32;
typeTrans[Sdollar] = CMO_STRING;
if (OxVersion >= 199907170) {
typeTrans[SuniversalNumber] = CMO_ZZ;
}else{
typeTrans[SuniversalNumber] = CMO_ZZ_OLD;
}
typeTrans[Sarray] = CMO_LIST;
/* typeTrans[Spoly] = CMO_DMS; */
typeTrans[Spoly] = CMO_DISTRIBUTED_POLYNOMIAL;
typeTrans[Sdouble] = CMO_64BIT_MACHINE_DOUBLE;
typeTrans[CLASSNAME_ERROR_PACKET] = CMO_ERROR2;
typeTrans[CLASSNAME_mathcap] = CMO_MATHCAP;
typeTrans[CLASSNAME_indeterminate] = CMO_INDETERMINATE;
typeTrans[CLASSNAME_tree] = CMO_TREE;
typeTrans[CLASSNAME_recursivePolynomial] = CMO_RECURSIVE_POLYNOMIAL;
typeTrans[CLASSNAME_polynomialInOneVariable] = CMO_POLYNOMIAL_IN_ONE_VARIABLE;
init = 1;
}
ttt = typeTrans[obj.tag];
if (obj.tag == Sclass) {
ttt = typeTrans[ectag(obj)];
}
for (i=0; i<n; i++) {
if (ttt == cmo[i]) {
if (ttt != CMO_LIST) return(1);
else {
m = getoaSize(obj);
for (j=0; j<m; j++) {
if (!cmoCheck00(getoa(obj,j),cmo,n)) return(0);
}
return(1);
}
}
}
if (DebugMathCap) {
if (DebugMathCap && 1) {
fprintf(stderr,"Type translation table (internal object tag --> CMO tag)\n");
for (i=0; i<20; i++) {
printf("%d ", typeTrans[i]);
}
printf("\n");
}
fprintf(stderr,"The type of the argument object in sm1 is %d.\n",obj.tag);
fprintf(stderr,"The type of the argument object in CMO is %d.\n",ttt);
fprintf(stderr,"Available CMO tags in mathcap= %d elements : [ ",n);
for (i=0; i<n; i++) {
fprintf(stderr," %d ",cmo[i]);
}
fprintf(stderr," ] \n");
}
return(0);
}
int cmoCheckMathCap(struct object obj, struct object *obp)
{
struct object mathcap;
struct object cmolist;
struct object mathcapMain;
struct object mathcapThird;
struct object ox;
struct object oxtag;
struct object ob0;
int oxsize;
int n;
int i;
#define CMO_CHECK_MATH_CAP_LIST_SIZE 1024
int cmo[CMO_CHECK_MATH_CAP_LIST_SIZE];
if (obp == NULL) return(1);
/* printObject(*obp,0,stderr); for debug*/
if (obp->tag != Sarray) {
fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
printObject(*obp,0,stderr);
fprintf(stderr,"\n");
errorOxmisc2("cmoCheckMathCap: format error in the client->mathcapObjp field.\n");
}
mathcap = *obp;
/* Example of mathcap
[ $mathcap-object$ ,
[ [ 199909080 , $Ox_system=ox_sm1.plain$ , $Version=2.991106$ ,
$HOSTTYPE=i386$ ] ,
[ 262 , 263 , 264 , 265 , 266 , 268 , 269 , 272 , 273 , 275 ,
276 ] ,
[ [ 514 , [ 2130706434 , 1 , 2 , 4 , 5 , 17 , 19 , 20 , 22 , 23 , 24 , 25 , 26 , 30 , 31 , 60 , 61 , 27 , 33 , 40 , 16 , 34 ] ] ] ] ]
*/
n = getoaSize(mathcap);
if (n < 2) {
fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
printObject(*obp,0,stderr);
fprintf(stderr,"\n");
errorOxmisc2("cmoCheckMathCap: length of mathcap is wrong in the client->mathcapObjp field.\n");
}
ob0 = getoa(mathcap,0);
if (ob0.tag != Sdollar) {
fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
printObject(*obp,0,stderr);
fprintf(stderr,"\n");
errorOxmisc2("cmoCheckMathCap: The first field must be the string mathcap-object.\n");
}
if (strcmp(KopString(ob0),"mathcap-object") != 0) {
fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
printObject(*obp,0,stderr);
fprintf(stderr,"\n");
errorOxmisc2("cmoCheckMathCap: The mathcap must be of the form [(mathcap-object) [...]]\n");
}
/* I should check
getoa(getoa(mathcap,1),2)
contains OX_DATA.
It has not yet implemented.
*/
mathcapMain = getoa(mathcap,1);
if (mathcapMain.tag != Sarray) {
fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
printObject(mathcapMain,0,stderr);
fprintf(stderr,"\n");
errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array.\n");
}
if (getoaSize(mathcapMain) < 3) {
fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
printObject(mathcapMain,0,stderr);
fprintf(stderr,"\n");
errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array of which length is more than 2.\n");
}
mathcapThird = getoa(mathcapMain,2);
oxsize = getoaSize(mathcapThird);
for (i=0; i<oxsize; i++) {
ox = getoa(mathcapThird,i);
if (ox.tag != Sarray) {
fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
printObject(*obp,0,stderr);
fprintf(stderr,"\n");
errorOxmisc2("cmoCheckMathCap: the third element of mathcap is a list of lists.");
}
if (getoaSize(ox) != 0) {
oxtag = getoa(ox,0);
if (oxtag.tag != Sinteger) {
fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
printObject(*obp,0,stderr);
fprintf(stderr,"\n");
errorOxmisc2("cmoCheckMathCap: the third element of mathcap must be [OX_DATA_xxx, [ ]].");
}
if (KopInteger(oxtag) == OX_DATA) {
if (getoaSize(ox) > 1) {
cmolist = getoa(ox,1);
if (cmolist.tag != Sarray) {
fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
printObject(*obp,0,stderr);
fprintf(stderr,"\n");
errorOxmisc2("cmoCheckMathCap: mathcap[1] must be an array of integers.\n");
}
n = getoaSize(cmolist);
if (n > CMO_CHECK_MATH_CAP_LIST_SIZE) {
errorOxmisc2("cmoCheckMathCap: Too big cmo list.\n");
}
for (i=0; i<n; i++) {
cmo[i] = KopInteger(getoa(cmolist,i));
}
}else{
fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
printObject(*obp,0,stderr);
fprintf(stderr,"\nox=");
printObject(ox,0,stderr);
errorOxmisc2("cmoCheckMathCap: [OX_DATA, cmolist]");
}
}
}
}
return(cmoCheck00(obj,cmo,n));
}
struct object KoxGenPortFile(void) {
struct object ob;
ob = KpoString(oxGenPortFile());
return(ob);
}
void KoxRemovePortFile(void) {
oxRemovePortFile();
}
void oxPushMathCap(struct mathCap *mathcap)
{
struct object rob;
rob = newMathCap(mathcap);
Kpush(rob);
}
struct object KoxGenPass(void) {
struct object rob;
rob = KpoString(oxGenPass());
return(rob);
}
struct object KoxGetPort(struct object host)
{
struct object rob;
int fdStream, fdControl;
int portStream, portControl;
extern int OpenedSocket;
char *sname;
rob = NullObject;
if (host.tag != Sdollar) {
errorOxmisc2("KoxGetPort: argument is not a string.");
return(rob);
}
sname = KopString(host);
fdControl = socketOpen(sname,0);
portControl = OpenedSocket;
fdStream = socketOpen(sname,0);
portStream = OpenedSocket;
rob = newObjectArray(4);
putoa(rob,0,KpoInteger(fdStream));
putoa(rob,1,KpoInteger(portStream));
putoa(rob,2,KpoInteger(fdControl));
putoa(rob,3,KpoInteger(portControl));
return(rob);
}
struct object KoxCreateClient2(struct object peer,
struct object ipmask,
struct object pass)
{
struct object rob;
oxclientp client;
int fdStream, portStream, fdControl, portControl;
int i;
struct object ob1;
rob.tag = Snull;
if (peer.tag != Sarray) {
errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl]");
return(rob);
}
if (getoaSize(peer) != 4) {
errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl] of size 4.");
return(rob);
}
for (i=0; i<4; i++) {
ob1 = getoa(peer,i);
if (ob1.tag != Sinteger) {
errorOxmisc2("KoxCreateClient2(): The element of the first argument must be an integer.");
}
}
fdStream = KopInteger(getoa(peer,0));
portStream = KopInteger(getoa(peer,1));
fdControl = KopInteger(getoa(peer,2));
portControl = KopInteger(getoa(peer,3));
if (ipmask.tag != Sinteger) {
errorOxmisc2("KoxCreateClient2(): ipmask must be an integer.");
}
if (pass.tag != Sdollar) {
errorOxmisc2("KoxCreateClient2(): pass must be a string.");
}
client = oxCreateClient2(fdStream, portStream, fdControl, portControl,
KopInteger(ipmask), KopString(pass));
if (client == NULL) {
errorOxmisc2("KoxCreateClient2(): Open error.");
return(rob);
}
rob = newObjectArray(N_OF_CLIENT_FIELDS);
oxClientToObject(client,rob);
return(rob);
}
errorOxmisc2(char *s) {
fprintf(MyErrorOut,"error in oxmisc2.c: %s\n",s);
errorKan1("%s\n"," ");
}