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