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