Annotation of OpenXM/src/ox_ntl/oxserv.c, Revision 1.1
1.1 ! iwane 1: /* $OpenXM$ */
! 2:
! 3: #include <stdio.h>
! 4: #include <stdlib.h>
! 5: #include <string.h>
! 6: #include <errno.h>
! 7:
! 8: #include "oxserv.h"
! 9:
! 10:
! 11: #define DPRINTF(x) printf x; fflush(stdout)
! 12:
! 13: #define delete_cmo(m)
! 14:
! 15: #define OXSERV_INIT_STACK_SIZE 2048
! 16: #define OXSERV_EXT_STACK_SIZE 2048
! 17:
! 18: #if 0
! 19: /*===========================================================================*
! 20: * for DEBUG
! 21: *===========================================================================*/
! 22: #include <stdarg.h>
! 23: void
! 24: dprintf(const char *fmt, ...)
! 25: {
! 26: FILE *fp;
! 27: va_list ap;
! 28: va_start(ap, fmt);
! 29:
! 30: fp = fopen("error.txt", "a");
! 31:
! 32: vfprintf(fp, fmt, ap);
! 33:
! 34: fflush(fp);
! 35: fclose(fp);
! 36:
! 37: va_end(ap);
! 38: }
! 39: #endif
! 40:
! 41: /*===========================================================================*
! 42: * Global Variables.
! 43: *===========================================================================*/
! 44: /* cmo stack */
! 45: static int G_ox_stack_size = 0;
! 46: static int G_ox_stack_pointer = 0;
! 47: static cmo **G_ox_stack = NULL;
! 48:
! 49: /* ox */
! 50: static cmo_mathcap *G_oxserv_mathcap = NULL;
! 51:
! 52: /* User Function */
! 53: static cmo *(*G_userExecuteFunction)(const char *, cmo **, int) = NULL;
! 54: static cmo *(*G_userExecuteStringParser)(const char *) = NULL;
! 55:
! 56: static cmo *(*G_convertCmo)(cmo *) = NULL; /* convert user object ==> cmo */
! 57:
! 58: /*===========================================================================*
! 59: * CMO STACK FUNCTIONs
! 60: *===========================================================================*/
! 61: /*****************************************************************************
! 62: * return the number of cmo in the stack.
! 63: * PARAM : NONE
! 64: * RETURN : the number of cmo in the stack.
! 65: *****************************************************************************/
! 66: #define oxserv_get_stack_pointer() G_ox_stack_pointer
! 67:
! 68:
! 69: /*****************************************************************************
! 70: * initialize stack.
! 71: * PARAM : NONE
! 72: * RETURN : if success return OXSERV_SUCCESS, else OXSERV_FAILURE.
! 73: *****************************************************************************/
! 74: static int
! 75: oxserv_init_stack(void)
! 76: {
! 77: free(G_ox_stack);
! 78:
! 79: G_ox_stack_pointer = 0;
! 80: G_ox_stack_size = OXSERV_INIT_STACK_SIZE;
! 81: G_ox_stack = (cmo **)malloc(G_ox_stack_size * sizeof(cmo *));
! 82: if (G_ox_stack == NULL) {
! 83: DPRINTF(("server: %d: %s\n", errno, strerror(errno)));
! 84: return (OXSERV_FAILURE);
! 85: }
! 86: return (OXSERV_SUCCESS);
! 87: }
! 88:
! 89: /*****************************************************************************
! 90: *
! 91: * PARAM : NONE
! 92: * RETURN : if success return OXSERV_SUCCESS, else OXSERV_FAILURE.
! 93: *****************************************************************************/
! 94: static int
! 95: oxserv_extend_stack(void)
! 96: {
! 97: int size2 = G_ox_stack_size + OXSERV_EXT_STACK_SIZE;
! 98: cmo **stack2 = (cmo **)malloc(size2 * sizeof(cmo *));
! 99: if (stack2 == NULL) {
! 100: DPRINTF(("server: %d: %s\n", errno, strerror(errno)));
! 101: return (OXSERV_FAILURE);
! 102: }
! 103:
! 104: memcpy(stack2, G_ox_stack, G_ox_stack_size * sizeof(cmo *));
! 105: free(G_ox_stack);
! 106:
! 107: G_ox_stack = stack2;
! 108: G_ox_stack_size = size2;
! 109:
! 110: return (OXSERV_SUCCESS);
! 111: }
! 112:
! 113: /*****************************************************************************
! 114: * push a cmo onto the topof the stack.
! 115: * PARAM : m : the cmo to be pushed on the stack.
! 116: * RETURN : if success return OXSERV_SUCCESS, else OXSERV_FAILURE.
! 117: *****************************************************************************/
! 118: static int
! 119: oxserv_push(cmo *m)
! 120: {
! 121: int ret;
! 122:
! 123: if (G_ox_stack_pointer >= G_ox_stack_size) {
! 124: ret = oxserv_extend_stack();
! 125: if (ret != OXSERV_SUCCESS)
! 126: return (ret);
! 127: }
! 128:
! 129: G_ox_stack[G_ox_stack_pointer] = m;
! 130: G_ox_stack_pointer++;
! 131:
! 132: return (OXSERV_SUCCESS);
! 133: }
! 134:
! 135: /*****************************************************************************
! 136: * remove thd CMO at the top of this stack and
! 137: * returns that cmo as the value of this function.
! 138: * PARAM : NONE
! 139: * RETURN : CMO at the top of the stack.
! 140: *****************************************************************************/
! 141: static cmo *
! 142: oxserv_pop(void)
! 143: {
! 144: cmo *c;
! 145: if (G_ox_stack_pointer > 0) {
! 146: G_ox_stack_pointer--;
! 147: c = G_ox_stack[G_ox_stack_pointer];
! 148: G_ox_stack[G_ox_stack_pointer] = NULL;
! 149: return (c);
! 150: }
! 151: return (NULL);
! 152: }
! 153:
! 154: /*****************************************************************************
! 155: * return the cmo at the specified position in the stack without removing it from the stack.
! 156: * PARAM : NONE
! 157: * RETURN: thd cmo at the specified position in the stack.
! 158: *****************************************************************************/
! 159: static cmo *
! 160: oxserv_get(int i)
! 161: {
! 162: if (i < G_ox_stack_pointer && i >= 0) {
! 163: return (G_ox_stack[i]);
! 164: }
! 165: return (NULL);
! 166: }
! 167:
! 168:
! 169: /*****************************************************************************
! 170: * return the cmo at the top of the stack without removing it from the stack.
! 171: * PARAM : NONE
! 172: * RETURN: the cmo at the top of the stack.
! 173: *****************************************************************************/
! 174: static cmo *
! 175: oxserv_peek(void)
! 176: {
! 177: return (oxserv_get(G_ox_stack_pointer - 1));
! 178: }
! 179:
! 180: /*****************************************************************************
! 181: *
! 182: * defined for SM_pops
! 183: *
! 184: * PARAM : n : remove count
! 185: * RETURN: NONE
! 186: *****************************************************************************/
! 187: static void
! 188: oxserv_remove(int n)
! 189: {
! 190: int i;
! 191: cmo *m;
! 192:
! 193: if (n > G_ox_stack_size)
! 194: n = G_ox_stack_size;
! 195:
! 196: for (i = 0; i < n; i++) {
! 197: --G_ox_stack_pointer;
! 198: m = G_ox_stack[G_ox_stack_pointer];
! 199: G_ox_stack[G_ox_stack_pointer] = NULL;
! 200: delete_cmo(m);
! 201: }
! 202: }
! 203:
! 204:
! 205: /*===========================================================================*
! 206: * OX_SERVER
! 207: *===========================================================================*/
! 208:
! 209: /*****************************************************************************
! 210: * pop n and to discard element from the stack
! 211: * PARAM : fd : OXFILE
! 212: * RETURN: NONE
! 213: *****************************************************************************/
! 214: static void
! 215: oxserv_sm_popCMO(OXFILE *fd)
! 216: {
! 217: cmo *m = oxserv_pop();
! 218: if (m == NULL) {
! 219: m = new_cmo_null();
! 220: } else if (G_convertCmo) {
! 221: m = G_convertCmo(m);
! 222: }
! 223:
! 224: send_ox_cmo(fd, m);
! 225:
! 226: delete_cmo(m);
! 227: }
! 228:
! 229: /*****************************************************************************
! 230: * pop an cmo from stack, convert it into a string according to the
! 231: * output format of the local system, and send the string.
! 232: * PARAM : fd : OXFILE
! 233: * RETURN: NONE
! 234: *****************************************************************************/
! 235: static void
! 236: oxserv_sm_popString(OXFILE *fd)
! 237: {
! 238: char *str;
! 239: cmo *m = oxserv_pop();
! 240: cmo_string *m_str;
! 241:
! 242: if (m == NULL)
! 243: m = new_cmo_null();
! 244:
! 245: str = new_string_set_cmo(m);
! 246:
! 247: m_str = new_cmo_string(str);
! 248:
! 249: send_ox_cmo(fd, (cmo *)m_str);
! 250:
! 251: delete_cmo(m);
! 252: delete_cmo(m_str);
! 253:
! 254: /* free(str); */
! 255: }
! 256:
! 257: /*****************************************************************************
! 258: * pop n and to discard element from the stack
! 259: * PARAM : fd : OXFILE
! 260: * RETURN: NONE
! 261: *****************************************************************************/
! 262: static void
! 263: oxserv_sm_pops()
! 264: {
! 265: cmo_int32 *c;
! 266:
! 267: c = (cmo_int32 *)oxserv_pop(); /* suppose */
! 268:
! 269: oxserv_remove(c->i)
! 270:
! 271: delete_cmo(c);
! 272: }
! 273:
! 274: /*****************************************************************************
! 275: * for SM_getsp
! 276: *
! 277: * PARAM : fd : OXFILE
! 278: * RETURN: NONE
! 279: *****************************************************************************/
! 280: static void
! 281: oxserv_sm_getsp()
! 282: {
! 283: cmo_int32 *m = new_cmo_int32(oxserv_get_stack_pointer());
! 284: oxserv_push((cmo *)m);
! 285: }
! 286:
! 287: /*****************************************************************************
! 288: *
! 289: * PARAM : ver :
! 290: * : vstr :
! 291: * : sysname:
! 292: * : cmos :
! 293: * : sms :
! 294: * RETURN: NONE
! 295: * SEE : oxserv_set();
! 296: *****************************************************************************/
! 297: static void
! 298: oxserv_mathcap_init(int ver, char *vstr, char *sysname, int *cmos, int *sms)
! 299: {
! 300: int i;
! 301:
! 302: int local_sms[] = {
! 303: SM_popCMO,
! 304: SM_mathcap,
! 305: SM_setMathCap,
! 306: SM_pops,
! 307: SM_getsp,
! 308: SM_popString,
! 309: SM_pushCMOtag,
! 310: 0,
! 311: SM_executeFunction,
! 312: SM_dupErrors,
! 313: SM_executeStringByLocalParser,
! 314: SM_executeStringByLocalParserInBatchMode,
! 315: SM_shutdown,
! 316: 0,
! 317: };
! 318:
! 319: /* depend on ox_toolkit */
! 320: int local_cmos[] = {
! 321: CMO_ERROR2,
! 322: CMO_NULL,
! 323: CMO_INT32,
! 324: CMO_STRING,
! 325: CMO_MATHCAP,
! 326: CMO_LIST,
! 327: CMO_MONOMIAL32,
! 328: CMO_ZZ,
! 329: CMO_ZERO,
! 330: CMO_RECURSIVE_POLYNOMIAL,
! 331: CMO_DISTRIBUTED_POLYNOMIAL,
! 332: CMO_POLYNOMIAL_IN_ONE_VARIABLE,
! 333: CMO_DMS_GENERIC,
! 334: CMO_RING_BY_NAME,
! 335: CMO_INDETERMINATE,
! 336: CMO_TREE,
! 337: CMO_LAMBDA,
! 338: 0,
! 339: CMO_QQ,
! 340: CMO_ATTRIBUTE_LIST,
! 341: CMO_DMS,
! 342: CMO_DMS_OF_N_VARIABLES,
! 343: CMO_LIST_R,
! 344: CMO_INT32COEFF,
! 345: CMO_RATIONAL,
! 346: CMO_DATUM,
! 347: 0,
! 348: };
! 349:
! 350: if (sms == NULL) {
! 351: sms = local_sms;
! 352:
! 353: for (i = 0; sms[i] != 0; i++)
! 354: ;
! 355: if (G_userExecuteFunction != NULL)
! 356: sms[i++] = SM_executeFunction;
! 357:
! 358: if (G_userExecuteStringParser != NULL) {
! 359: sms[i++] = SM_executeStringByLocalParser;
! 360: sms[i++] = SM_executeStringByLocalParserInBatchMode;
! 361: }
! 362:
! 363: sms[i] = 0;
! 364: }
! 365: if (cmos == NULL)
! 366: cmos = local_cmos;
! 367:
! 368: mathcap_init(ver, vstr, sysname, cmos, sms);
! 369:
! 370: delete_cmo(G_oxserv_mathcap);
! 371:
! 372: G_oxserv_mathcap = mathcap_get(new_mathcap());
! 373: }
! 374:
! 375: static void
! 376: oxserv_sm_mathcap()
! 377: {
! 378: if (G_oxserv_mathcap == NULL) {
! 379: oxserv_mathcap_init(0, "", "oxserv", NULL, NULL);
! 380: }
! 381:
! 382: oxserv_push((cmo *)G_oxserv_mathcap);
! 383: }
! 384:
! 385: static void
! 386: oxserv_sm_executeStringByLocalParserInBatchMode(void)
! 387: {
! 388: cmo_string *str = (cmo_string *)oxserv_peek();
! 389: cmo *c;
! 390: c = G_userExecuteStringParser(str->s);
! 391: oxserv_push(c);
! 392: }
! 393:
! 394: static void
! 395: oxserv_sm_executeStringByLocalParser(void)
! 396: {
! 397: cmo_string *str = (cmo_string *)oxserv_pop();
! 398: cmo *c;
! 399: c = G_userExecuteStringParser(str->s);
! 400: oxserv_push(c);
! 401: }
! 402:
! 403:
! 404:
! 405: static void
! 406: oxserv_sm_executeFunction(void)
! 407: {
! 408: int i;
! 409: cmo_string *name = (cmo_string *)oxserv_pop();
! 410: cmo_int32 *cnt = (cmo_int32 *)oxserv_pop();
! 411: cmo **arg = (cmo **)malloc(cnt->i * sizeof(cmo *));
! 412: cmo *ret;
! 413:
! 414: for (i = 0; i < cnt->i; i++) {
! 415: arg[i] = oxserv_pop();
! 416: }
! 417:
! 418: /* user function */
! 419: ret = G_userExecuteFunction(name->s, arg, cnt->i);
! 420:
! 421: oxserv_push(ret);
! 422:
! 423: for (i = 0; i < cnt->i; i++) {
! 424: delete_cmo(arg[i]);
! 425: }
! 426:
! 427: delete_cmo(name);
! 428: delete_cmo(cnt);
! 429:
! 430: free(arg);
! 431: }
! 432:
! 433: static void
! 434: oxserv_sm_pushCMOtag()
! 435: {
! 436: cmo *c = oxserv_peek();
! 437: cmo_int32 *tag = new_cmo_int32(c->tag);
! 438:
! 439: oxserv_push((cmo *)tag);
! 440: }
! 441:
! 442:
! 443: static void
! 444: oxserv_sm_dupErrors()
! 445: {
! 446: cmo_list *list;
! 447: cmo *c;
! 448: int i;
! 449:
! 450: list = new_cmo_list();
! 451:
! 452: for (i = 0; i < oxserv_get_stack_pointer(); i++) {
! 453: c = oxserv_get(i);
! 454: if (c->tag == CMO_ERROR2) {
! 455: list_append(list, c);
! 456: }
! 457: }
! 458:
! 459: oxserv_push((cmo *)list);
! 460: }
! 461:
! 462:
! 463: static int
! 464: oxserv_receive_and_execute_sm_command(OXFILE *fd)
! 465: {
! 466: int code = receive_int32(fd);
! 467:
! 468: DPRINTF(("SM_CODE=%d=0x%x\n", code, code));
! 469:
! 470: switch (code) {
! 471: case SM_popCMO:
! 472: oxserv_sm_popCMO(fd);
! 473: break;
! 474: case SM_executeStringByLocalParser:
! 475: if (G_userExecuteStringParser)
! 476: oxserv_sm_executeStringByLocalParser();
! 477: break;
! 478: case SM_executeStringByLocalParserInBatchMode:
! 479: if (G_userExecuteStringParser)
! 480: oxserv_sm_executeStringByLocalParserInBatchMode();
! 481: break;
! 482: case SM_pops:
! 483: oxserv_sm_pops();
! 484: break;
! 485: case SM_popString:
! 486: oxserv_sm_popString(fd);
! 487: break;
! 488: case SM_getsp:
! 489: oxserv_sm_getsp();
! 490: break;
! 491: case SM_mathcap:
! 492: oxserv_sm_mathcap();
! 493: break;
! 494: case SM_setMathCap:
! 495: /* dont support */
! 496: oxserv_pop();
! 497: break;
! 498: case SM_executeFunction:
! 499: if (G_userExecuteFunction)
! 500: oxserv_sm_executeFunction();
! 501: break;
! 502: case SM_pushCMOtag:
! 503: oxserv_sm_pushCMOtag();
! 504: break;
! 505: case SM_dupErrors:
! 506: oxserv_sm_dupErrors();
! 507: break;
! 508: default:
! 509: break;
! 510: }
! 511: return (OXSERV_SUCCESS);
! 512: }
! 513:
! 514:
! 515: /*****************************************************************************
! 516: * reveice ox_data
! 517: * PARAM : fd : OXFILE
! 518: * RETURN: NONE
! 519: *****************************************************************************/
! 520: int
! 521: oxserv_receive(OXFILE *fd)
! 522: {
! 523: int tag;
! 524: cmo *c;
! 525: int ret = OXSERV_SUCCESS;
! 526:
! 527: tag = receive_ox_tag(fd);
! 528:
! 529: DPRINTF(("oxserv_TAG=%d=0x%x\n", tag, tag));
! 530: switch (tag) {
! 531: case OX_DATA:
! 532: c = receive_cmo(fd);
! 533: DPRINTF(("CMO_TAG=%d=0x%x\n", c->tag, c->tag));
! 534: oxserv_push(c);
! 535: break;
! 536:
! 537: case OX_COMMAND:
! 538: ret = oxserv_receive_and_execute_sm_command(fd);
! 539: break;
! 540:
! 541: default:
! 542: DPRINTF(("receive unknown ox_tag: %d=0x%x\n", tag, tag));
! 543: return (OXSERV_FAILURE);
! 544: }
! 545:
! 546: return (ret);
! 547: }
! 548:
! 549:
! 550: /*****************************************************************************
! 551: * initialize oxserver
! 552: *
! 553: * PARAM : see oxserv_mathcap_init()
! 554: * RETURN: NONE
! 555: * SEE : oxserv_mathcap_init()
! 556: * : oxserv_set();
! 557: *****************************************************************************/
! 558: int
! 559: oxserv_init(OXFILE *oxfp, int ver, char *vstr, char *sysname, int *cmos, int *sms)
! 560: {
! 561: int ret;
! 562:
! 563: ret = oxserv_init_stack();
! 564: if (ret != OXSERV_SUCCESS)
! 565: return (ret);
! 566:
! 567: oxserv_mathcap_init(ver, vstr, sysname, cmos, sms);
! 568:
! 569: oxf_determine_byteorder_server(oxfp);
! 570:
! 571: return (OXSERV_SUCCESS);
! 572: }
! 573:
! 574:
! 575: /*****************************************************************************
! 576: * set oxserver
! 577: * PARAM : mode : mode
! 578: * :
! 579: * : ptr :
! 580: * : rsv : reserve space.
! 581: * RETURN: NONE
! 582: * SEE :
! 583: *****************************************************************************/
! 584: int
! 585: oxserv_set(int mode, void *ptr, void *rsv)
! 586: {
! 587: switch (mode) {
! 588: case OXSERV_SET_EXECUTE_FUNCTION:
! 589: G_userExecuteFunction = (cmo *(*)(const char *, cmo **, int))ptr;
! 590: break;
! 591: case OXSERV_SET_EXECUTE_STRING_PARSER:
! 592: G_userExecuteStringParser = (cmo *(*)(const char *))ptr;
! 593: break;
! 594: case OXSERV_SET_CONVERT_CMO:
! 595: G_convertCmo = (cmo *(*)(cmo *))ptr;
! 596: break;
! 597: default:
! 598: return (OXSERV_FAILURE);
! 599: }
! 600:
! 601:
! 602: return (OXSERV_SUCCESS);
! 603: }
! 604:
! 605:
! 606: /*****************************************************************************
! 607: * destroy
! 608: * PARAM : mode : mode
! 609: * :
! 610: * : ptr :
! 611: * : rsv : reserve space.
! 612: * RETURN: NONE
! 613: * SEE :
! 614: *****************************************************************************/
! 615: void
! 616: oxserv_dest()
! 617: {
! 618: free(G_ox_stack);
! 619: }
! 620:
! 621:
! 622: #if 0
! 623:
! 624: cmo *
! 625: oxserv_executeFunction(const char *func, cmo **arg, int argc)
! 626: {
! 627: int i;
! 628:
! 629: printf("%s()\n", func);
! 630:
! 631: for (i = 0; i < argc; i++) {
! 632: printf("\t%2d: %s\n", i, new_string_set_cmo(arg[i]));
! 633: }
! 634:
! 635: return ((cmo *)new_cmo_int32(0));
! 636: }
! 637:
! 638: int
! 639: main(int argc, char *argv[])
! 640: {
! 641: int fd = 3;
! 642: int i;
! 643: int ret;
! 644:
! 645: OXFILE *oxfp = oxf_open(fd);
! 646:
! 647: ox_stderr_init(stderr);
! 648:
! 649: oxserv_init(0, "$Date: 2003/11/02 16:39:16 $", "oxserv", NULL, NULL);
! 650:
! 651: DPRINTF(("main - start\n"));
! 652: for (i = 0;; i++) {
! 653: DPRINTF(("@"));
! 654: ret = oxserv_receive(oxfp);
! 655: if (ret != OXSERV_SUCCESS)
! 656: break;
! 657: }
! 658:
! 659: oxf_close(fd);
! 660: delete_cmo(G_oxserv_mathcap);
! 661:
! 662: return (0);
! 663: }
! 664:
! 665: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>