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