Annotation of OpenXM/src/oxc/sm_ext.c, Revision 1.2
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.2 ! ohara 2: /* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.1 2000/10/13 06:05:12 ohara Exp $ */
1.1 ohara 3:
4: #include <stdio.h>
5: #include <stdlib.h>
6: #include <unistd.h>
7: #include <string.h>
1.2 ! ohara 8: #include <sys/signal.h>
1.1 ohara 9: #include <ox_toolkit.h>
10: #include "sm.h"
11:
12: /* ultra loose data base. */
13: static db db_localfunc[] = {
14: {lf_oxc_open, "oxc_open"},
15: {NULL, NULL}
16: };
17:
18: static db db_sm[] = {
19: {sm_executeFunction, SM_executeFunction},
20: {sm_mathcap, SM_mathcap},
21: {sm_popCMO, SM_popCMO},
22: {sm_pops, SM_pops},
23: {NULL, NULL}
24: };
25:
26: __inline__
27: static int (*db_search(void *key, db *dbs, int (*cmp)(void *, void *)))()
28: {
29: while (dbs->key != NULL) {
30: if (cmp(key, dbs->key) == 0) {
31: return dbs->func_ptr;
32: }
33: dbs++;
34: }
35: return NULL;
36: }
37:
38: static int (*lookup_localfunction(char *name))()
39: {
40: return db_search(name, db_localfunc, strcmp);
41: }
42:
43: /*
44: Normally local functions push a return value to the stack.
45: but, if error occurs, then these return non-positive numbers and
46: the sm_executeFunction push an error object.
47: */
48: void sm_executeFunction(OXFILE *oxfp)
49: {
50: int (*func)(OXFILE *);
51: int retcode = 0;
52: cmo *ob = pop();
53: if (ob->tag == CMO_STRING) {
54: func = lookup_localfunction(((cmo_string *)ob)->s);
55: if (func != NULL) {
56: if ((retcode = func(oxfp)) > 0) {
57: return;
58: }
59: }
60: }
61: push_error(retcode, ob);
62: }
63:
64: /* getargs() set number of popped objects to argc. */
65: static int getargs(cmo ***args)
66: {
67: cmo **argv;
68: int i;
69: int argc = -1;
70: cmo_int32 *m = pop();
71:
72: if (m->tag != CMO_INT32 || (argc = m->i) < 0) {
73: fprintf(stderr, "oxc: invalid arguments\n");
74: }else {
75: argv = (cmo **)malloc(sizeof(cmo *)*argc);
76: for(i=0; i<argc; i++) {
77: argv[i] = pop();
78: }
79: *args = argv;
80: }
81: return argc;
82: }
83:
84: static int pids[1024] = {0};
85: static int pid_ptr = 0;
86:
1.2 ! ohara 87: int pid_lookup(int pid)
! 88: {
! 89: int i;
! 90: for(i=0; i<pid_ptr; i++) {
! 91: if (pids[i] == pid) {
! 92: return i;
! 93: }
! 94: }
! 95: return -1;
! 96: }
! 97:
! 98: int pid_registed(int pid)
! 99: {
! 100: return pid_lookup(pid)+1;
! 101: }
! 102:
! 103: int pid_regist(int pid)
1.1 ohara 104: {
105: if (pid_ptr < 1024) {
106: pids[pid_ptr++] = pid;
107: return pid;
108: }
109: return 0;
110: }
111:
1.2 ! ohara 112: void pid_delete(int pid)
! 113: {
! 114: int i = pid_lookup(pid);
! 115: if (i >= 0 && i != --pid_ptr) {
! 116: pids[i] = pids[pid_ptr];
! 117: }
! 118: }
! 119:
1.1 ohara 120: int lf_oxc_open()
121: {
122: cmo **argv;
123: char *cmd;
124: int port;
125: int pid;
126:
127: if (getargs(&argv) != 2 || argv[0]->tag != CMO_STRING
128: || argv[1]->tag != CMO_INT32) {
129: fprintf(stderr, "oxc: invalid arguments\n");
130: return -1;
131: }
132:
133: cmd = ((cmo_string *)argv[0])->s;
134: port = ((cmo_int32 *)argv[1])->i;
135: pid = lf_oxc_open_main(cmd, port);
136: if (pid > 0) {
137: push(new_cmo_int32(pid));
1.2 ! ohara 138: pid_regist(pid);
1.1 ohara 139: }
140: return pid;
141: }
142:
143: void sm_mathcap(OXFILE *oxfp)
144: {
145: cmo_mathcap *m = pop();
146: if (m->tag == CMO_MATHCAP) {
147: mathcap_update(m);
148: }else {
149: push_error(-1, m);
150: /* an error object must be pushed */
151: }
152: }
1.2 ! ohara 153:
! 154: void sm_control_kill(OXFILE *oxfp)
! 155: {
! 156: cmo_int32 *m = pop();
! 157: int pid = m->i;
! 158: if (m->tag != CMO_INT32 || !pid_registed(pid)) {
! 159: push_error(-1, m);
! 160: }else {
! 161: kill(pid, SIGKILL);
! 162: pid_delete(pid);
! 163: }
! 164: }
! 165:
! 166: void sm_control_reset(OXFILE *oxfp)
! 167: {
! 168: cmo_int32 *m = pop();
! 169: int pid = m->i;
! 170: if (m->tag != CMO_INT32 || !pid_registed(pid)) {
! 171: push_error(-1, m);
! 172: }else {
! 173: kill(pid, SIGUSR1);
! 174: }
! 175: }
! 176:
! 177: void sm_control_start_engin(OXFILE *oxfp);
1.1 ohara 178:
179: static int intcmp(int key1, int key2)
180: {
181: return key1 != key2;
182: }
183:
184:
185: int (*sm_search_f(int code))()
186: {
187: return db_search(code, db_sm, intcmp);
188: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>