[BACK]Return to oxserv.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_ntl

Annotation of OpenXM/src/ox_ntl/oxserv.c, Revision 1.8

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>