=================================================================== RCS file: /home/cvs/OpenXM/src/ox_math/sm_ext.c,v retrieving revision 1.1 retrieving revision 1.8 diff -u -p -r1.1 -r1.8 --- OpenXM/src/ox_math/sm_ext.c 2000/12/03 21:45:48 1.1 +++ OpenXM/src/ox_math/sm_ext.c 2003/02/12 08:28:41 1.8 @@ -1,5 +1,5 @@ /* -*- mode: C; coding: euc-japan -*- */ -/* $OpenXM$ */ +/* $OpenXM: OpenXM/src/ox_math/sm_ext.c,v 1.7 2003/02/04 14:27:43 ohara Exp $ */ /* Copyright (C) Katsuyoshi OHARA, 2000. @@ -10,137 +10,103 @@ See OpenXM/Copyright/Copyright.mathlink for detail. */ -/* - Remarks: - file descripter 3 and 4 are already opened by the parent process. -*/ - #include #include #include -#include -#include +#include #include #include "sm.h" +#include "mlo.h" -extern int flag_mlo_symbol; +static struct { int (*func_ptr)(); int key; } tbl_smcmd[] = { + {sm_executeFunction, SM_executeFunction}, + {sm_executeStringByLocalParser, SM_executeStringByLocalParser}, + {sm_executeStringByLocalParser, SM_executeStringByLocalParserInBatchMode}, + {sm_mathcap, SM_mathcap}, + {sm_set_mathcap, SM_setMathCap}, + {sm_popString, SM_popString}, + {sm_popCMO, SM_popCMO}, + {sm_pops, SM_pops}, + {shutdown, SM_shutdown}, + {NULL, NULL} +}; -/* MathLink independent */ -static cmo **stack = NULL; -static int stack_ptr = 0; -static int stack_size = 0; -OXFILE *stack_oxfp = NULL; +extern OXFILE *stack_oxfp; -#define DIFFERENCE_OF_STACK 1024 +static sigset_t mask; +static int flag_state_interrupting = 0; -void stack_extend() +/* state management for the OpenXM robust interruption */ +void sm_state_set_interrupting() { - int newsize = stack_size + DIFFERENCE_OF_STACK; - cmo **newstack = (cmo **)malloc(sizeof(cmo *)*newsize); - if (stack != NULL) { - memcpy(newstack, stack, sizeof(cmo *)*stack_size); - free(stack); - } - stack_size = newsize; - stack = newstack; + ml_state_set(RESERVE_INTERRUPTION); } -void push(cmo* m) +int sm_state_interrupting() { -#if DEBUG - symbol_t symp; - - if (m->tag == CMO_STRING) { - fprintf(stderr, "ox_math:: a CMO_STRING(%s) was pushed.\n", ((cmo_string *)m)->s); - }else { - symp = lookup_by_tag(m->tag); - fprintf(stderr, "ox_math:: a %s was pushed.\n", symbol_get_key(symp)); - } -#endif - if (stack_ptr >= stack_size) { - stack_extend(); - } - stack[stack_ptr] = m; - stack_ptr++; + return ml_state(RESERVE_INTERRUPTION); } -/* if the stack is empty, then pop() returns (CMO_NULL). */ -cmo *pop() +void sm_state_clear_interrupting() { - if (stack_ptr > 0) { - return stack[--stack_ptr]; - } - return new_cmo_null(); + ml_state_clear_all(); } -void pops(int n) +/* handling OpenXM singals */ +static void sm_sighandler() { - stack_ptr -= n; - if (stack_ptr < 0) { - stack_ptr = 0; - } + sm_state_set_interrupting(); } -void push_error(int errcode, cmo* pushback) +/* generating the mask pattern */ +void sm_siginit() { - return push((cmo *)make_error_object(errcode, pushback)); + signal(SIGUSR1, sm_sighandler); + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); } -/* -If error occurs, then -an sm_*() function returns non-zero and -an error obect is set by a function which calls sm_*(). -*/ -int sm_popCMO(OXFILE* oxfp) +void sm_sigmask() { - cmo* m = pop(); -#ifdef DEBUG - symbol_t symp = lookup_by_tag(m->tag); - fprintf(stderr, "ox_math:: opecode = SM_popCMO. (%s)\n", symbol_get_key(symp)); -#endif + sigprocmask(SIG_BLOCK, &mask, NULL); +} - if (m != NULL) { - send_ox_cmo(oxfp, m); - return 0; - } - return SM_popCMO; +void sm_sigunmask() +{ + sigprocmask(SIG_UNBLOCK, &mask, NULL); } -int sm_pops(OXFILE* oxfp) +int (*sm_search_f(int code))() { - cmo* m = pop(); - if (m != NULL && m->tag == CMO_INT32) { - pops(((cmo_int32 *)m)->i); - return 0; + int i; + for (i=0; tbl_smcmd[i].key != NULL; i++) { + if (code == tbl_smcmd[i].key) { + return tbl_smcmd[i].func_ptr; + } } - return ERROR_ID_UNKNOWN_SM; + return NULL; } /* MathLink dependent */ -int sm_popString(OXFILE* oxfp) +void sm_popString() { char *s; cmo *err; - cmo *m; - -#ifdef DEBUG - fprintf(stderr, "ox_math:: opecode = SM_popString.\n"); -#endif - - m = pop(); + cmo *m = pop(); if (m->tag == CMO_STRING) { - send_ox_cmo(oxfp, m); + send_ox_cmo(stack_oxfp, m); }else if ((s = new_string_set_cmo(m)) != NULL) { - send_ox_cmo(oxfp, (cmo *)new_cmo_string(s)); + send_ox_cmo(stack_oxfp, (cmo *)new_cmo_string(s)); }else { err = make_error_object(SM_popString, m); - send_ox_cmo(oxfp, err); + send_ox_cmo(stack_oxfp, err); } - return 0; } int local_execute(char *s) { + extern int flag_mlo_symbol; + if(*s == 'i') { switch(s[1]) { case '+': @@ -156,15 +122,10 @@ int local_execute(char *s) } /* The following function is depend on an implementation of a server. */ -int sm_executeStringByLocalParser(OXFILE* oxfp) +void sm_executeStringByLocalParser() { - symbol_t symp; cmo* m = pop(); char *s = NULL; -#ifdef DEBUG - fprintf(stderr, "ox_math:: opecode = SM_executeStringByLocalParser.\n"); -#endif - if (m->tag == CMO_STRING && strlen(s = ((cmo_string *)m)->s) != 0) { if (s[0] == ':') { @@ -173,19 +134,19 @@ int sm_executeStringByLocalParser(OXFILE* oxfp) /* for mathematica */ /* Sending the string `s' to mathematica for its evaluation. */ ml_evaluateStringByLocalParser(s); + sm_sigunmask(); ml_select(); - push(receive_mlo()); + sm_sigmask(); + m = ml_return(); + push(m); } - return 0; - } -#ifdef DEBUG - symp = lookup_by_tag(m->tag); - fprintf(stderr, "ox_math:: error. the top of stack is %s.\n", symbol_get_key(symp)); -#endif - return SM_executeStringByLocalParser; + }else { + ox_printf(" <%s>", get_symbol_by_tag(m->tag)); + push_error(SM_executeStringByLocalParser, m); + } } -int sm_executeFunction(OXFILE* oxfp) +void sm_executeFunction() { int i, argc; cmo **argv; @@ -193,12 +154,12 @@ int sm_executeFunction(OXFILE* oxfp) cmo* m; if ((m = pop()) == NULL || m->tag != CMO_STRING) { - return SM_executeFunction; + push_error(SM_executeFunction, m); } func = ((cmo_string *)m)->s; if ((m = pop()) == NULL || m->tag != CMO_INT32) { - return SM_executeFunction; + push_error(SM_executeFunction, m); } argc = ((cmo_int32 *)m)->i; @@ -207,78 +168,25 @@ int sm_executeFunction(OXFILE* oxfp) argv[i] = pop(); } ml_executeFunction(func, argc, argv); + sm_sigunmask(); ml_select(); - push(receive_mlo()); - return 0; + sm_sigmask(); + m = ml_return(); + push(m); } -int sm_mathcap(OXFILE* oxfp) +void sm_mathcap() { - push((cmo *)oxf_cmo_mathcap(oxfp)); - return 0; + push((cmo *)oxf_cmo_mathcap(stack_oxfp)); } -void sm_set_mathcap(OXFILE *oxfp) +void sm_set_mathcap() { cmo_mathcap *m = (cmo_mathcap *)pop(); if (m->tag == CMO_MATHCAP) { - oxf_mathcap_update(oxfp, m); + oxf_mathcap_update(stack_oxfp, m); }else { push_error(-1, m); /* an error object must be pushed */ } -} - -int receive_sm_command(OXFILE* oxfp) -{ - return receive_int32(oxfp); -} - -int execute_sm_command(OXFILE* oxfp, int code) -{ - int err = 0; -#ifdef DEBUG - symbol_t sp = lookup_by_tag(code); - fprintf(stderr, "ox_math:: %s received.\n", symbol_get_key(sp)); -#endif - - switch(code) { - case SM_popCMO: - err = sm_popCMO(oxfp); - break; - case SM_popString: - err = sm_popString(oxfp); - break; - case SM_mathcap: - err = sm_mathcap(oxfp); - break; - case SM_pops: - err = sm_pops(oxfp); - break; - case SM_executeStringByLocalParser: - case SM_executeStringByLocalParserInBatchMode: - err = sm_executeStringByLocalParser(oxfp); - break; - case SM_executeFunction: - err = sm_executeFunction(oxfp); - break; - case SM_shutdown: - shutdown(); - break; - case SM_setMathCap: - pop(); /* ignore */ - break; - default: - fprintf(stderr, "unknown command: %d.\n", code); - err = ERROR_ID_UNKNOWN_SM; - } - - if (err != 0) { - push((cmo *)make_error_object(err, new_cmo_null())); - } -} - -int sm_run(int code) -{ - return execute_sm_command(stack_oxfp, code); }