Annotation of OpenXM/src/ox_ntl/oxserv.c, Revision 1.7
1.7 ! iwane 1: /* $OpenXM: OpenXM/src/ox_ntl/oxserv.c,v 1.6 2004/07/04 11:38:42 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.3 iwane 8: #include <setjmp.h>
1.1 iwane 9:
10: #include "oxserv.h"
1.2 iwane 11: #include "oxstack.h"
1.1 iwane 12:
1.7 ! iwane 13: #include "gmp.h"
1.3 iwane 14: #include "gc/gc.h"
1.1 iwane 15:
1.7 ! iwane 16: #define DPRINTF(x) printf x; (void)fflush(stdout)
1.1 iwane 17:
1.3 iwane 18: #define FP stdout
1.7 ! iwane 19: #define EPRINTF(x) fprintf x; (void)fflush(FP)
1.3 iwane 20:
1.1 iwane 21:
22: /*===========================================================================*
1.2 iwane 23: * MACRO
1.1 iwane 24: *===========================================================================*/
1.3 iwane 25: #define oxserv_get_cmo_tag(m) ((G_getCmoTag == NULL) ? m->tag : G_getCmoTag(m))
1.1 iwane 26:
27:
1.2 iwane 28: #define oxserv_delete_cmo(c) \
29: do { \
1.3 iwane 30: if (c != NULL) { \
31: if (G_DeleteCmo != NULL) \
1.5 iwane 32: G_DeleteCmo((cmo *)c); \
1.3 iwane 33: else \
1.2 iwane 34: c = NULL; \
1.3 iwane 35: } \
1.2 iwane 36: } while (0)
37:
1.1 iwane 38:
39: /*===========================================================================*
1.2 iwane 40: * Global Variables.
1.1 iwane 41: *===========================================================================*/
1.2 iwane 42: /* ox */
43: static OXFILE *G_oxfilep = NULL;
44: static cmo_mathcap *G_oxserv_mathcap = NULL;
1.1 iwane 45:
1.3 iwane 46: /* signal */
1.4 iwane 47: int G_oxserv_sigusr1flag = 0;
48: int G_oxserv_sigusr1cnt = 0;
1.3 iwane 49: static jmp_buf G_jmpbuf;
50:
1.2 iwane 51: /* User Function */
52: static void (*G_userExecuteFunction)(const char *, cmo **, int) = NULL;
53: static void (*G_userExecuteStringParser)(const char *) = NULL;
1.1 iwane 54:
1.2 iwane 55: static cmo *(*G_convertCmo)(cmo *) = NULL; /* convert user object ==> cmo */
1.1 iwane 56:
1.2 iwane 57: static void (*G_DeleteCmo)(cmo *) = NULL;
1.1 iwane 58:
1.2 iwane 59: static int (*G_getCmoTag)(cmo *) = NULL;
1.1 iwane 60:
1.3 iwane 61:
62: /*===========================================================================*
63: * CMO_ERROR2
64: *===========================================================================*/
65: #define new_cmo_error2_string(msg) new_cmo_error2((cmo *)new_cmo_string(msg))
66:
67:
68: static void
69: oxserv_push_errormes(char *msg)
70: {
71: EPRINTF((FP, "%s\n", msg));
72: oxstack_push((cmo *)new_cmo_error2_string(msg));
73: }
74:
75: /*===========================================================================*
76: * synchronized malloc
77: *===========================================================================*/
78: void *
79: oxserv_malloc(size_t size)
80: {
81: void *ptr;
82:
83: BLOCK_INPUT();
84: ptr = GC_malloc(size);
85: UNBLOCK_INPUT();
86:
87: return (ptr);
88: }
89:
90: void
91: oxserv_free(void *ptr, size_t size)
92: {
93: /* nothing */
94: }
95:
96: void *
97: oxserv_realloc(void *org, size_t old, size_t size)
98: {
99: void *ptr;
100:
101: BLOCK_INPUT();
102: ptr = GC_realloc(org, size);
103: UNBLOCK_INPUT();
104:
105: return (ptr);
106: }
107:
108:
109:
1.1 iwane 110: /*===========================================================================*
111: * OX_SERVER
112: *===========================================================================*/
113:
114: /*****************************************************************************
1.2 iwane 115: * -- SM_popCMO --
116: * pop an object from the stack, convert it into a serialized from according
117: * to the standard CMO encoding scheme, and send it to the stream
118: *
1.1 iwane 119: * PARAM : fd : OXFILE
120: * RETURN: NONE
121: *****************************************************************************/
122: static void
123: oxserv_sm_popCMO(OXFILE *fd)
124: {
1.3 iwane 125: cmo *m, *n;
126: m = oxstack_pop();
1.1 iwane 127: if (m == NULL) {
1.3 iwane 128: EPRINTF((FP, "stack underflow in popCMO\n"));
1.1 iwane 129: m = new_cmo_null();
130: } else if (G_convertCmo) {
1.3 iwane 131: n = G_convertCmo(m);
1.4 iwane 132: if (m != n) {
1.3 iwane 133: oxserv_delete_cmo(m);
1.4 iwane 134: m = n;
135: }
1.1 iwane 136: }
137:
138: send_ox_cmo(fd, m);
139:
1.2 iwane 140: oxserv_delete_cmo(m);
1.1 iwane 141: }
142:
143: /*****************************************************************************
1.2 iwane 144: * -- SM_popString --
1.1 iwane 145: * pop an cmo from stack, convert it into a string according to the
146: * output format of the local system, and send the string.
1.2 iwane 147: *
1.1 iwane 148: * PARAM : fd : OXFILE
149: * RETURN: NONE
150: *****************************************************************************/
151: static void
152: oxserv_sm_popString(OXFILE *fd)
153: {
154: char *str;
1.2 iwane 155: cmo *m = oxstack_pop();
1.1 iwane 156: cmo_string *m_str;
157:
1.3 iwane 158: if (m == NULL) {
159: EPRINTF((FP, "stack underflow in popString\n"));
1.1 iwane 160: m = new_cmo_null();
1.3 iwane 161: }
1.1 iwane 162:
163: str = new_string_set_cmo(m);
164:
165: m_str = new_cmo_string(str);
166:
167: send_ox_cmo(fd, (cmo *)m_str);
168:
1.2 iwane 169: oxserv_delete_cmo(m);
1.5 iwane 170: oxserv_delete_cmo(m_str);
1.1 iwane 171:
1.2 iwane 172: /* free(str); */
1.1 iwane 173: }
174:
175: /*****************************************************************************
1.2 iwane 176: * -- SM_pops --
1.1 iwane 177: * pop n and to discard element from the stack
1.2 iwane 178: *
179: * PARAM : NONE
1.1 iwane 180: * RETURN: NONE
181: *****************************************************************************/
182: static void
183: oxserv_sm_pops()
184: {
185: cmo_int32 *c;
1.2 iwane 186: cmo *m;
187: int n;
188: int i;
189:
190: c = (cmo_int32 *)oxstack_pop(); /* suppose */
1.3 iwane 191: if (c == NULL) {
192: EPRINTF((FP, "stack underflow in pops\n"));
193: return ;
194: }
1.1 iwane 195:
1.2 iwane 196: n = oxstack_get_stack_pointer();
197: if (c->i < n)
198: n = c->i;
1.1 iwane 199:
1.2 iwane 200: for (i = 0; i < n; i++) {
201: m = oxstack_pop();
202: oxserv_delete_cmo(m);
203: }
204:
1.5 iwane 205: oxserv_delete_cmo(c);
1.1 iwane 206:
207: }
208:
209: /*****************************************************************************
1.2 iwane 210: * -- SM_getsp --
211: * push the current stack pointer onto the stack.
1.1 iwane 212: *
213: * PARAM : fd : OXFILE
214: * RETURN: NONE
215: *****************************************************************************/
216: static void
217: oxserv_sm_getsp()
218: {
1.2 iwane 219: cmo_int32 *m = new_cmo_int32(oxstack_get_stack_pointer());
220: oxstack_push((cmo *)m);
1.1 iwane 221: }
222:
223: /*****************************************************************************
224: *
225: * PARAM : ver :
226: * : vstr :
227: * : sysname:
228: * : cmos :
229: * : sms :
230: * RETURN: NONE
231: * SEE : oxserv_set();
232: *****************************************************************************/
233: static void
234: oxserv_mathcap_init(int ver, char *vstr, char *sysname, int *cmos, int *sms)
235: {
236: int i;
237:
238: int local_sms[] = {
239: SM_popCMO,
240: SM_mathcap,
241: SM_setMathCap,
242: SM_pops,
243: SM_getsp,
244: SM_popString,
245: SM_pushCMOtag,
246: 0,
247: SM_executeFunction,
248: SM_dupErrors,
249: SM_executeStringByLocalParser,
250: SM_executeStringByLocalParserInBatchMode,
251: SM_shutdown,
252: 0,
253: };
254:
255: /* depend on ox_toolkit */
256: int local_cmos[] = {
257: CMO_ERROR2,
258: CMO_NULL,
259: CMO_INT32,
260: CMO_STRING,
261: CMO_MATHCAP,
262: CMO_LIST,
263: CMO_MONOMIAL32,
264: CMO_ZZ,
265: CMO_ZERO,
266: CMO_RECURSIVE_POLYNOMIAL,
267: CMO_DISTRIBUTED_POLYNOMIAL,
268: CMO_POLYNOMIAL_IN_ONE_VARIABLE,
269: CMO_DMS_GENERIC,
270: CMO_RING_BY_NAME,
271: CMO_INDETERMINATE,
272: CMO_TREE,
273: CMO_LAMBDA,
274: 0,
275: CMO_QQ,
276: CMO_ATTRIBUTE_LIST,
277: CMO_DMS,
278: CMO_DMS_OF_N_VARIABLES,
279: CMO_LIST_R,
280: CMO_INT32COEFF,
281: CMO_RATIONAL,
282: CMO_DATUM,
283: 0,
284: };
285:
286: if (sms == NULL) {
287: sms = local_sms;
288:
289: for (i = 0; sms[i] != 0; i++)
290: ;
291: if (G_userExecuteFunction != NULL)
292: sms[i++] = SM_executeFunction;
293:
294: if (G_userExecuteStringParser != NULL) {
295: sms[i++] = SM_executeStringByLocalParser;
296: sms[i++] = SM_executeStringByLocalParserInBatchMode;
297: }
298:
299: sms[i] = 0;
300: }
301: if (cmos == NULL)
302: cmos = local_cmos;
303:
304: mathcap_init(ver, vstr, sysname, cmos, sms);
305:
1.5 iwane 306: oxserv_delete_cmo(G_oxserv_mathcap);
1.1 iwane 307:
308: G_oxserv_mathcap = mathcap_get(new_mathcap());
309: }
310:
1.2 iwane 311: /*****************************************************************************
312: * -- SM_mathcap --
313: * push the mathcap of the server.
314: *
315: * PARAM : NONE
316: * RETURN: NONE
317: *****************************************************************************/
1.1 iwane 318: static void
319: oxserv_sm_mathcap()
320: {
321: if (G_oxserv_mathcap == NULL) {
322: oxserv_mathcap_init(0, "", "oxserv", NULL, NULL);
323: }
324:
1.2 iwane 325: oxstack_push((cmo *)G_oxserv_mathcap);
1.1 iwane 326: }
327:
1.2 iwane 328: /*****************************************************************************
329: * -- SM_executeStringByLocalParserInBatchMode --
330: * peek a character string s, parse it by the local parser of the stack machine,
331: * and interpret by the local interpreter.
332: *
333: * PARAM : NONE
334: * RETURN: NONE
335: *****************************************************************************/
1.1 iwane 336: static void
337: oxserv_sm_executeStringByLocalParserInBatchMode(void)
338: {
1.2 iwane 339: cmo_string *str = (cmo_string *)oxstack_peek();
1.3 iwane 340: if (str == NULL) {
341: oxserv_push_errormes("stack underflow in executeStringByLocalParserInBatchMode");
342: return ;
343: }
1.2 iwane 344: G_userExecuteStringParser(str->s);
1.1 iwane 345: }
346:
1.2 iwane 347: /*****************************************************************************
348: * -- SM_executeStringByLocalParser --
349: * pop a character string s, parse it by the local parser of the stack machine,
350: * and interpret by the local interpreter.
351: *
352: * PARAM : NONE
353: * RETURN: NONE
354: *****************************************************************************/
1.1 iwane 355: static void
356: oxserv_sm_executeStringByLocalParser(void)
357: {
1.2 iwane 358: cmo_string *str = (cmo_string *)oxstack_pop();
1.3 iwane 359: if (str == NULL) {
360: oxserv_push_errormes("stack underflow in executeStringByLocalParser");
361: return ;
362: }
1.2 iwane 363: G_userExecuteStringParser(str->s);
1.1 iwane 364: }
365:
366:
367:
1.2 iwane 368: /*****************************************************************************
369: * -- SM_executeFunction --
370: * pop s as a function name, pop n as the number of arguments and to execute a
371: * local function s with n arguments poped from the stack.
372: *
1.4 iwane 373: * suppose G_userExecuteFunction not equal NULL
374: *
1.2 iwane 375: * PARAM : NONE
376: * RETURN: NONE
377: *****************************************************************************/
1.1 iwane 378: static void
379: oxserv_sm_executeFunction(void)
380: {
381: int i;
1.2 iwane 382: cmo_string *name = (cmo_string *)oxstack_pop();
383: cmo_int32 *cnt = (cmo_int32 *)oxstack_pop();
1.3 iwane 384: cmo **arg;
385:
386:
387: if (name == NULL || cnt == NULL) {
388: oxserv_push_errormes("stack underflow in executeFunction");
389: return ;
390: }
1.1 iwane 391:
1.4 iwane 392: arg = (cmo **)malloc(cnt->i * sizeof(cmo *));
1.1 iwane 393: for (i = 0; i < cnt->i; i++) {
1.2 iwane 394: arg[i] = oxstack_pop();
1.3 iwane 395: if (arg[i] == NULL) {
396: oxserv_push_errormes("stack underflow in executeFunction");
1.4 iwane 397:
398: for (i--; i >= 0; i--)
399: oxserv_delete_cmo(arg[i]);
400: free(arg);
1.3 iwane 401: return ;
402: }
1.1 iwane 403: }
404:
405: /* user function */
1.2 iwane 406: G_userExecuteFunction(name->s, arg, cnt->i);
1.1 iwane 407:
408:
409: for (i = 0; i < cnt->i; i++) {
1.2 iwane 410: oxserv_delete_cmo(arg[i]);
1.1 iwane 411: }
412:
1.5 iwane 413: oxserv_delete_cmo(name);
414: oxserv_delete_cmo(cnt);
1.1 iwane 415:
416: free(arg);
417: }
418:
1.2 iwane 419: /*****************************************************************************
420: * -- SM_pushCMOtag --
421: * push the CMO tag of the top object on the stack.
422: *
423: * PARAM : NONE
424: * RETURN: NONE
425: *****************************************************************************/
1.1 iwane 426: static void
427: oxserv_sm_pushCMOtag()
428: {
1.2 iwane 429: cmo *c = oxstack_peek();
1.3 iwane 430: cmo_int32 *tag = new_cmo_int32(oxserv_get_cmo_tag(c));
1.2 iwane 431: oxstack_push((cmo *)tag);
1.1 iwane 432: }
433:
434:
1.3 iwane 435: /*****************************************************************************
436: * -- SM_dupErrors --
437: *
438: * PARAM : NONE
439: * RETURN: NONE
440: *****************************************************************************/
1.1 iwane 441: static void
442: oxserv_sm_dupErrors()
443: {
444: cmo_list *list;
445: cmo *c;
446: int i;
447:
448: list = new_cmo_list();
449:
1.2 iwane 450: for (i = 0; i < oxstack_get_stack_pointer(); i++) {
451: c = oxstack_get(i);
1.1 iwane 452: if (c->tag == CMO_ERROR2) {
453: list_append(list, c);
454: }
455: }
456:
1.2 iwane 457: oxstack_push((cmo *)list);
1.1 iwane 458: }
459:
1.3 iwane 460:
461:
462:
463: /*****************************************************************************
464: * -- SM_control_reset_connection -- signal handler for SIGUSR1 --
465: *
466: * PARAM : NONE
1.4 iwane 467: *
468: * : if (sig == 0) called UNBLOCK_INPUT()
1.3 iwane 469: * RETURN: NONE
470: *****************************************************************************/
1.4 iwane 471: void
1.2 iwane 472: oxserv_sm_control_reset_connection(int sig)
473: {
474: int tag;
475: OXFILE *fd = G_oxfilep;
476:
1.4 iwane 477: if (G_oxserv_sigusr1cnt > 0) {
478: G_oxserv_sigusr1flag = 1;
479: return ;
480: }
481:
482:
1.3 iwane 483: DPRINTF(("reset -- start ==> "));
1.4 iwane 484: G_oxserv_sigusr1flag = 0;
485:
1.2 iwane 486: send_ox_tag(fd, OX_SYNC_BALL);
487:
488: oxstack_init_stack();
489:
490: for (;;) {
491: tag = receive_ox_tag(fd);
1.3 iwane 492: DPRINTF(("[OX:%d=0x%x]", tag, tag));
1.2 iwane 493: if (tag == OX_SYNC_BALL)
494: break;
495: if (tag == OX_DATA)
496: receive_cmo(fd);
1.3 iwane 497: else
498: receive_int32(fd);
1.2 iwane 499: }
1.3 iwane 500: DPRINTF((" <== end.\n"));
501:
1.4 iwane 502:
1.3 iwane 503: longjmp(G_jmpbuf, sig);
1.2 iwane 504: }
1.1 iwane 505:
1.3 iwane 506: /*****************************************************************************
507: * execute sm command
508: *
509: * PARAM : NONE
510: * RETURN: NONE
511: *****************************************************************************/
1.1 iwane 512: static int
1.3 iwane 513: oxserv_execute_sm_command(OXFILE *fd, int code)
1.1 iwane 514: {
1.3 iwane 515:
516: DPRINTF(("[SM:%d=0x%x]", code, code));
1.1 iwane 517:
518: switch (code) {
1.3 iwane 519: case SM_popCMO: /* 262 */
1.1 iwane 520: oxserv_sm_popCMO(fd);
521: break;
1.3 iwane 522: case SM_executeStringByLocalParser: /* 268 */
1.1 iwane 523: if (G_userExecuteStringParser)
524: oxserv_sm_executeStringByLocalParser();
525: break;
1.3 iwane 526: case SM_executeStringByLocalParserInBatchMode: /* 274 */
1.1 iwane 527: if (G_userExecuteStringParser)
528: oxserv_sm_executeStringByLocalParserInBatchMode();
529: break;
1.3 iwane 530: case SM_pops: /* 265 */
1.1 iwane 531: oxserv_sm_pops();
532: break;
1.3 iwane 533: case SM_popString: /* 263 */
1.1 iwane 534: oxserv_sm_popString(fd);
535: break;
1.3 iwane 536: case SM_getsp: /* 275 */
1.1 iwane 537: oxserv_sm_getsp();
538: break;
1.3 iwane 539: case SM_mathcap: /* 264 */
1.1 iwane 540: oxserv_sm_mathcap();
541: break;
1.3 iwane 542: case SM_setMathCap: /* 273 */
1.1 iwane 543: /* dont support */
1.2 iwane 544: oxstack_pop();
1.1 iwane 545: break;
1.3 iwane 546: case SM_executeFunction: /* 269 */
1.1 iwane 547: if (G_userExecuteFunction)
548: oxserv_sm_executeFunction();
549: break;
1.3 iwane 550: case SM_pushCMOtag: /* 277 */
1.1 iwane 551: oxserv_sm_pushCMOtag();
552: break;
1.3 iwane 553: case SM_dupErrors: /* 276 */
1.1 iwane 554: oxserv_sm_dupErrors();
555: break;
1.3 iwane 556: case SM_popSerializedLocalObject:
557: case SM_setName:
558: case SM_evalName:
559: case SM_beginBlock:
560: case SM_endBlock:
561: case SM_shutdown:
562: case SM_executeFunctionAndPopCMO:
563: case SM_executeFunctionAndPopSerializedLocalObject:
1.2 iwane 564: case SM_control_reset_connection:
565: case SM_control_reset_connection_server:
1.1 iwane 566: default:
567: break;
568: }
569: return (OXSERV_SUCCESS);
570: }
571:
572:
1.2 iwane 573:
1.1 iwane 574: /*****************************************************************************
575: * reveice ox_data
1.2 iwane 576: *
1.1 iwane 577: * PARAM : fd : OXFILE
578: * RETURN: NONE
579: *****************************************************************************/
1.3 iwane 580: static int
581: oxserv_ox_receive(OXFILE *fd)
1.1 iwane 582: {
583: int tag;
584: cmo *c;
585: int ret = OXSERV_SUCCESS;
1.3 iwane 586: int code;
1.1 iwane 587:
588: tag = receive_ox_tag(fd);
589:
590: switch (tag) {
591: case OX_DATA:
1.4 iwane 592: BLOCK_INPUT();
1.1 iwane 593: c = receive_cmo(fd);
1.4 iwane 594: UNBLOCK_INPUT();
1.3 iwane 595: DPRINTF(("[CMO:%d=0x%x]", c->tag, c->tag));
1.2 iwane 596: oxstack_push(c);
1.1 iwane 597: break;
598:
599: case OX_COMMAND:
1.3 iwane 600: code = receive_int32(fd);
601: ret = oxserv_execute_sm_command(fd, code);
1.1 iwane 602: break;
603:
604: default:
605: DPRINTF(("receive unknown ox_tag: %d=0x%x\n", tag, tag));
606: return (OXSERV_FAILURE);
607: }
608:
609: return (ret);
610: }
611:
1.3 iwane 612: int
613: oxserv_receive(OXFILE *fd)
614: {
615: int i = 0;
616: int ret;
617:
618: ret = setjmp(G_jmpbuf);
619: if (ret == 0) {
620: DPRINTF(("setjmp first time -- %d\n", ret));
621: } else {
622: DPRINTF(("setjmp return from longjmp() -- %d -- \n", ret));
623: }
624:
625: for (;; i++) {
626: ret = oxserv_ox_receive(fd);
627: if (ret != OXSERV_SUCCESS)
628: break;
629: }
630: return (ret);
631: }
632:
1.1 iwane 633:
634: /*****************************************************************************
635: * initialize oxserver
636: *
637: * PARAM : see oxserv_mathcap_init()
1.2 iwane 638: * RETURN: success : OXSERV_SUCCESS
639: * : failure : OXSERV_FAILURE
1.1 iwane 640: * SEE : oxserv_mathcap_init()
641: * : oxserv_set();
642: *****************************************************************************/
643: int
644: oxserv_init(OXFILE *oxfp, int ver, char *vstr, char *sysname, int *cmos, int *sms)
645: {
646: int ret;
647:
1.3 iwane 648: DPRINTF(("init start\n"));
649:
1.2 iwane 650: ret = oxstack_init_stack();
1.1 iwane 651: if (ret != OXSERV_SUCCESS)
652: return (ret);
653:
1.2 iwane 654: G_oxfilep = oxfp;
655:
1.1 iwane 656: oxserv_mathcap_init(ver, vstr, sysname, cmos, sms);
657:
1.2 iwane 658: signal(SIGUSR1, oxserv_sm_control_reset_connection);
659:
1.3 iwane 660: /* initialize GMP memory functions. */
661: mp_set_memory_functions(oxserv_malloc, oxserv_realloc, oxserv_free);
662:
663: /* session start */
1.1 iwane 664: oxf_determine_byteorder_server(oxfp);
665:
666: return (OXSERV_SUCCESS);
667: }
668:
669:
670: /*****************************************************************************
1.3 iwane 671: * set oxserver behavior
1.2 iwane 672: *
1.1 iwane 673: * PARAM : mode : mode
674: * :
675: * : ptr :
676: * : rsv : reserve space.
1.2 iwane 677: * RETURN: success : OXSERV_SUCCESS
678: * : failure : OXSERV_FAILURE
1.1 iwane 679: * SEE :
680: *****************************************************************************/
681: int
682: oxserv_set(int mode, void *ptr, void *rsv)
683: {
684: switch (mode) {
685: case OXSERV_SET_EXECUTE_FUNCTION:
1.2 iwane 686: G_userExecuteFunction = (void (*)(const char *, cmo **, int))ptr;
1.1 iwane 687: break;
688: case OXSERV_SET_EXECUTE_STRING_PARSER:
1.2 iwane 689: G_userExecuteStringParser = (void (*)(const char *))ptr;
1.1 iwane 690: break;
691: case OXSERV_SET_CONVERT_CMO:
692: G_convertCmo = (cmo *(*)(cmo *))ptr;
693: break;
1.2 iwane 694: case OXSERV_SET_DELETE_CMO:
695: G_DeleteCmo = (void (*)(cmo *))ptr;
696: break;
697: case OXSERV_SET_GET_CMOTAG:
698: G_getCmoTag = (int (*)(cmo *))ptr;
699: break;
1.1 iwane 700: default:
701: return (OXSERV_FAILURE);
702: }
703:
704:
705: return (OXSERV_SUCCESS);
706: }
707:
708:
709: /*****************************************************************************
710: * destroy
1.2 iwane 711: *
712: * PARAM : NONE
1.1 iwane 713: * RETURN: NONE
714: *****************************************************************************/
715: void
716: oxserv_dest()
717: {
1.5 iwane 718: oxserv_delete_cmo(G_oxserv_mathcap);
1.4 iwane 719:
1.2 iwane 720: oxstack_dest();
1.1 iwane 721: }
722:
723:
1.2 iwane 724: #if __OXSERV_DEBUG
725: /*===========================================================================*
726: * DEBUG
727: *===========================================================================*/
728:
1.1 iwane 729:
1.4 iwane 730: void
1.1 iwane 731: oxserv_executeFunction(const char *func, cmo **arg, int argc)
732: {
733: int i;
734:
735: printf("%s()\n", func);
736:
737: for (i = 0; i < argc; i++) {
738: printf("\t%2d: %s\n", i, new_string_set_cmo(arg[i]));
739: }
740:
1.4 iwane 741: return ;
1.1 iwane 742: }
743:
1.2 iwane 744: /*****************************************************************************
745: * main
746: *
747: * PARAM : NONE
748: * RETURN: NONE
749: *****************************************************************************/
1.1 iwane 750: int
751: main(int argc, char *argv[])
752: {
753: int fd = 3;
754: int i;
755: int ret;
756:
757: OXFILE *oxfp = oxf_open(fd);
758:
759: ox_stderr_init(stderr);
760:
1.4 iwane 761: oxserv_set(OXSERV_SET_EXECUTE_FUNCTION, oxserv_executeFunction, NULL);
762:
1.2 iwane 763: oxserv_init(oxfp, 0, "$Date: 2003/11/02 16:39:16 $", "oxserv", NULL, NULL);
1.1 iwane 764:
1.4 iwane 765: ret = oxserv_receive(oxfp);
1.1 iwane 766:
1.4 iwane 767: oxserv_dest();
1.2 iwane 768: oxf_close(oxfp);
1.1 iwane 769:
770: return (0);
771: }
772:
773: #endif
1.2 iwane 774:
775:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>