Annotation of OpenXM/src/ox_python/ox_python.c, Revision 1.7
1.7 ! takayama 1: /* $OpenXM: OpenXM/src/ox_python/ox_python.c,v 1.6 2022/01/02 00:23:25 takayama Exp $
1.1 takayama 2: */
3:
4: #include <stdio.h>
5: #include <stdlib.h>
6: #include <setjmp.h>
7: #include <string.h>
8: #include <unistd.h>
9: #include <signal.h>
10: #include <math.h>
11: #include "ox_python.h"
12:
13: OXFILE *fd_rw;
14:
15: #define INIT_S_SIZE 2048
16: #define EXT_S_SIZE 2048
17:
18: static int stack_size = 0;
19: static int stack_pointer = 0;
20: static cmo **stack = NULL;
21:
22: int Debug=1;
23:
24: void show_stack_top() {
25: cmo *data;
26: if (stack_pointer > 0) {
27: data=stack[stack_pointer-1];
28: print_cmo(data); printf("\n");
29: }else {
30: printf("The stack is empty.\n");
31: }
32: }
33:
34: void *gc_realloc(void *p,size_t osize,size_t nsize)
35: { return (void *)GC_realloc(p,nsize);}
36:
37: void gc_free(void *p,size_t size)
38: { GC_free(p);}
39:
40: void init_gc()
41: { GC_INIT();
42: mp_set_memory_functions(GC_malloc,gc_realloc,gc_free);
43: }
44:
45: void initialize_stack()
46: {
47: stack_pointer = 0;
48: stack_size = INIT_S_SIZE;
49: stack = GC_malloc(stack_size*sizeof(cmo*));
50: }
51:
52: static void extend_stack()
53: {
54: int size2 = stack_size + EXT_S_SIZE;
55: cmo **stack2 = malloc(size2*sizeof(cmo*));
56: memcpy(stack2, stack, stack_size*sizeof(cmo *));
57: free(stack);
58: stack = stack2;
59: stack_size = size2;
60: }
61:
62: void push(cmo* m)
63: {
64: stack[stack_pointer] = m;
65: stack_pointer++;
66: if (stack_pointer >= stack_size) {
67: extend_stack();
68: }
69: }
70:
71: cmo* pop()
72: {
73: if (stack_pointer > 0) {
74: stack_pointer--;
75: return stack[stack_pointer];
76: }
77: return new_cmo_null();
78: }
79:
80: void pops(int n)
81: {
82: stack_pointer -= n;
83: if (stack_pointer < 0) {
84: stack_pointer = 0;
85: }
86: }
87:
88: #define OX_PYTHON_VERSION 2018090701
89: #define ID_STRING "2018/09/07 17:47:00"
90:
91: int sm_mathcap()
92: {
93: int available_cmo[]={
94: CMO_NULL,
95: CMO_INT32,
96: // CMO_DATUM,
97: CMO_STRING,
98: CMO_MATHCAP,
99: CMO_LIST,
100: // CMO_MONOMIAL32,
101: CMO_ZZ,
102: // CMO_QQ,
103: CMO_BIGFLOAT32,
104: CMO_COMPLEX,
105: CMO_IEEE_DOUBLE_FLOAT,
106: CMO_ZERO,
107: // CMO_DMS_GENERIC,
108: // CMO_RING_BY_NAME,
109: // CMO_INDETERMINATE,
110: // CMO_DISTRIBUTED_POLYNOMIAL,
111: // CMO_RECURSIVE_POLYNOMIAL,
112: // CMO_POLYNOMIAL_IN_ONE_VARIABLE,
113: CMO_TREE,
114: CMO_ERROR2,
115: 0};
116: int available_sm_command[]={
117: SM_popCMO,
118: SM_popString,
119: SM_mathcap,
120: SM_pops,
121: SM_executeStringByLocalParser,
122: SM_executeFunction,
123: SM_setMathCap,
124: SM_shutdown,
125: SM_control_kill,
126: SM_control_reset_connection,
127: SM_control_spawn_server,
128: SM_control_terminate_server,
129: 0};
130: mathcap_init(OX_PYTHON_VERSION, ID_STRING, "ox_python", available_cmo,available_sm_command);
131: push((cmo *)oxf_cmo_mathcap(fd_rw));
132: return 0;
133: }
134:
135: int sm_popCMO()
136: {
137: cmo* m = pop();
138:
139: if (m != NULL) {
140: send_ox_cmo(fd_rw, m);
141: return 0;
142: }
143: return SM_popCMO;
144: }
145:
146: cmo *make_error2(const char *reason,const char *fname,int line,int code)
147: {
148: // gsl_error_handler_t void handler(const char *reason,const char *file,int line, int gsl_errno)
149: cmo *ms;
150: cmo *err;
151: cmo *m;
152: cmo **argv;
153: int n;
154: char *s;
1.6 takayama 155: char s_tmp[256];
156: s = s_tmp;
1.1 takayama 157: n = 5;
158: argv = (cmo **) GC_malloc(sizeof(cmo *)*n);
1.6 takayama 159: ms = (cmo *)new_cmo_string("error"); argv[0] = ms;
160: if (reason != NULL) {s = (char *)GC_malloc(strlen(reason)+3);
161: strcpy(s,"\"");strcat(s,reason);strcat(s,"\"");
162: }else strcpy(s,"0");
1.1 takayama 163: ms = (cmo *) new_cmo_string(s); argv[1] = ms;
1.6 takayama 164: if (fname != NULL) {s = (char *)GC_malloc(strlen(fname)+3);
165: strcpy(s,"\"");strcat(s,fname);strcat(s,"\"");
166: }else strcpy(s,"0");
1.1 takayama 167: ms = (cmo *) new_cmo_string(s); argv[2] = ms;
168: err = (cmo *)new_cmo_int32(line); argv[3] = err;
169: err = (cmo *)new_cmo_int32(code); argv[4] = err;
170:
171: m = (cmo *)new_cmo_list_array((void *)argv,n);
172: return (m);
173: }
174:
175: int get_i()
176: {
177: cmo *c = pop();
178: if (c->tag == CMO_INT32) {
179: return ((cmo_int32 *)c)->i;
180: }else if (c->tag == CMO_ZZ) {
181: return mpz_get_si(((cmo_zz *)c)->mpz);
182: }else if (c->tag == CMO_NULL) {
183: return(0);
184: }else if (c->tag == CMO_ZERO) {
185: return(0);
186: }
187: myhandler("get_i: not an integer",NULL,0,-1);
188: return 0;
189: }
190:
191: void get_xy(int *x, int *y)
192: {
193: pop();
194: *x = get_i();
195: *y = get_i();
196: }
197:
198: void my_add_int32()
199: {
200: int x, y;
201: get_xy(&x, &y);
202: push((cmo *)new_cmo_int32(x+y));
203: }
204:
205: double get_double()
206: {
207: #define mympz(c) (((cmo_zz *)c)->mpz)
208: cmo *c = pop();
209: if (c->tag == CMO_INT32) {
210: return( (double) (((cmo_int32 *)c)->i) );
211: }else if (c->tag == CMO_IEEE_DOUBLE_FLOAT) {
212: return (((cmo_double *)c)->d); // see ox_toolkit.h
213: }else if (c->tag == CMO_ZZ) {
214: if ((mpz_cmp_si(mympz(c),(long int) 0x7fffffff)>0) ||
215: (mpz_cmp_si(mympz(c),(long int) -0x7fffffff)<0)) {
216: myhandler("get_double: out of int32",NULL,0,-1);
217: return(NAN);
218: }
219: return( (double) mpz_get_si(((cmo_zz *)c)->mpz));
220: }else if (c->tag == CMO_NULL) {
221: return(0);
222: }else if (c->tag == CMO_ZERO) {
223: return(0);
224: }
225: myhandler("get_double: not a double",NULL,0,-1);
226: return(NAN);
227: }
228: /* get_double() will be obsolted and will be replaced by cmo2double(c) */
229: double cmo2double(cmo *c)
230: {
231: #define mympz(c) (((cmo_zz *)c)->mpz)
232: if (c == NULL) c = pop();
233: if (c->tag == CMO_INT32) {
234: return( (double) (((cmo_int32 *)c)->i) );
235: }else if (c->tag == CMO_IEEE_DOUBLE_FLOAT) {
236: return (((cmo_double *)c)->d); // see ox_toolkit.h
237: }else if (c->tag == CMO_ZZ) {
238: if ((mpz_cmp_si(mympz(c),(long int) 0x7fffffff)>0) ||
239: (mpz_cmp_si(mympz(c),(long int) -0x7fffffff)<0)) {
240: myhandler("get_double: out of int32",NULL,0,-1);
241: return(NAN);
242: }
243: return( (double) mpz_get_si(((cmo_zz *)c)->mpz));
244: }else if (c->tag == CMO_NULL) {
245: return(0);
246: }else if (c->tag == CMO_ZERO) {
247: return(0);
248: }
249: myhandler("cmo2double: not a double",NULL,0,-1);
250: return(NAN);
251: }
252:
253: void my_add_double() {
254: double x,y;
255: pop();
256: y = get_double();
257: x = get_double();
258: push((cmo *)new_cmo_double(x+y));
259: }
260:
261: double *get_double_list(int *length) {
262: cmo *c;
263: cmo *entry;
264: cell *cellp;
265: double *d;
266: int n,i;
267: c = pop();
268: if (c->tag != CMO_LIST) {
269: // make_error2("get_double_list",NULL,0,-1);
270: *length=-1; return(0);
271: }
272: n = *length = list_length((cmo_list *)c);
273: d = (double *) GC_malloc(sizeof(double)*(*length+1));
274: cellp = list_first((cmo_list *)c);
275: entry = cellp->cmo;
276: for (i=0; i<n; i++) {
277: if (Debug) {
278: printf("entry[%d]=",i); print_cmo(entry); printf("\n");
279: }
280: if (entry->tag == CMO_INT32) {
281: d[i]=( (double) (((cmo_int32 *)entry)->i) );
282: }else if (entry->tag == CMO_IEEE_DOUBLE_FLOAT) {
283: d[i]=((cmo_double *)entry)->d;
284: }else if (entry->tag == CMO_ZZ) {
285: d[i]=( (double) mpz_get_si(((cmo_zz *)entry)->mpz));
286: }else if (entry->tag == CMO_NULL) {
287: d[i]= 0;
288: }else {
289: fprintf(stderr,"entries of the list should be int32 or zz or double\n");
290: *length = -1;
291: myhandler("get_double_list",NULL,0,-1);
292: return(NULL);
293: }
294: cellp = list_next(cellp);
295: entry = cellp->cmo;
296: }
297: return(d);
298: }
299: /* get_double_list will be obsolted and will be replaced by cmo2double_list() */
300: double *cmo2double_list(int *length,cmo *c) {
301: cmo *entry;
302: cell *cellp;
303: double *d;
304: int n,i;
305: if (c == NULL) c = pop();
306: if (c->tag != CMO_LIST) {
307: // make_error2("get_double_list",NULL,0,-1);
308: *length=-1; return(0);
309: }
310: n = *length = list_length((cmo_list *)c);
311: d = (double *) GC_malloc(sizeof(double)*(*length+1));
312: cellp = list_first((cmo_list *)c);
313: entry = cellp->cmo;
314: for (i=0; i<n; i++) {
315: if (Debug) {
316: printf("entry[%d]=",i); print_cmo(entry); printf("\n");
317: }
318: if (entry->tag == CMO_INT32) {
319: d[i]=( (double) (((cmo_int32 *)entry)->i) );
320: }else if (entry->tag == CMO_IEEE_DOUBLE_FLOAT) {
321: d[i]=((cmo_double *)entry)->d;
322: }else if (entry->tag == CMO_ZZ) {
323: d[i]=( (double) mpz_get_si(((cmo_zz *)entry)->mpz));
324: }else if (entry->tag == CMO_NULL) {
325: d[i]= 0;
326: }else {
327: fprintf(stderr,"entries of the list should be int32 or zz or double\n");
328: *length = -1;
329: myhandler("get_double_list",NULL,0,-1);
330: return(NULL);
331: }
332: cellp = list_next(cellp);
333: entry = cellp->cmo;
334: }
335: return(d);
336: }
337: void show_double_list() {
338: int n;
339: double *d;
340: int i;
341: pop(); // pop argument number;
342: d = get_double_list(&n);
343: if (n < 0) fprintf(stderr,"Error in the double list\n");
344: printf("show_double_list: length=%d\n",n);
345: for (i=0; i<n; i++) {
346: printf("%lg, ",d[i]);
347: }
348: printf("\n");
349: }
350:
351: char *get_string() {
352: cmo *c;
353: c = pop();
354: if (c->tag == CMO_STRING) {
355: return (((cmo_string *)c)->s);
356: }
357: // make_error2(-1);
358: return(NULL);
359: }
360:
361:
362: int sm_executeFunction()
363: {
364: cmo_string *func = (cmo_string *)pop();
365: if (func->tag != CMO_STRING) {
366: push(make_error2("sm_executeFunction, not CMO_STRING",NULL,0,-1));
367: return -1;
368: }
369: // Test functions
370: if (strcmp(func->s, "add_int32") == 0) {
371: my_add_int32();
372: }else if (strcmp(func->s,"add_double")==0) {
373: my_add_double();
374: }else if (strcmp(func->s,"show_double_list")==0) {
375: show_double_list();
376: }else if (strcmp(func->s,"restart")==0) {
377: pop(); restart();
1.2 takayama 378: }else if (strcmp(func->s,"PyRun_String")==0) {
379: my_PyRun_String();
380: }else if (strcmp(func->s,"eval")==0) {
1.4 takayama 381: my_eval2();
1.1 takayama 382: }else {
383: push(make_error2("sm_executeFunction, unknown function",NULL,0,-1));
384: return -1;
385: }
386: return(0);
387: }
388:
389: int sm_executeStringByLocalParser()
390: {
391: int status;
392: cmo_string *cmd = (cmo_string *)pop();
393: if (cmd->tag != CMO_STRING) {
394: push(make_error2("sm_executeStringByLocalParser, not CMO_STRING",NULL,0,-1));
395: return -1;
396: }
1.7 ! takayama 397: /*** {FILE *fp; fp=fopen("tmp-debug.txt","a"); fprintf(fp,"strlen=%d\n%s\n",strlen(cmd->s),cmd->s);fclose(fp); } ***/
1.1 takayama 398: status=PyRun_SimpleString(cmd->s);
399: // push(make_error2("sm_executeStringByLocalParser",NULL,0,-1));
400: push((cmo *)new_cmo_int32(status));
401: return(0);
1.2 takayama 402: /* Todo, set the flag by Py_InspectFlag to avoid exit after exception.
403: See PyRun_SimpleStringFlags, https://docs.python.jp/2.7/c-api/veryhigh.html
404: */
1.1 takayama 405: }
406:
407:
408: int receive_and_execute_sm_command()
409: {
410: int code = receive_int32(fd_rw);
411: switch(code) {
412: case SM_popCMO:
413: sm_popCMO();
414: break;
415: case SM_executeFunction:
416: sm_executeFunction();
417: break;
418: case SM_mathcap:
419: sm_mathcap();
420: break;
421: case SM_setMathCap:
422: pop();
423: break;
424: case SM_executeStringByLocalParser:
425: sm_executeStringByLocalParser();
426: break;
427: default:
428: ;
429: }
430: return(0);
431: }
432:
433: int receive()
434: {
435: int tag;
436:
437: tag = receive_ox_tag(fd_rw);
438: switch(tag) {
439: case OX_DATA:
440: push(receive_cmo(fd_rw));
441: if (Debug) show_stack_top();
442: break;
443: case OX_COMMAND:
444: if (Debug) show_stack_top();
445: receive_and_execute_sm_command();
446: break;
447: default:
448: ;
449: }
450: return 0;
451: }
452:
453: jmp_buf Ox_env;
454: int Ox_intr_usr1=0;
455: void usr1_handler(int sig)
456: {
457: Ox_intr_usr1=1;
458: longjmp(Ox_env,1);
459: }
460: void restart() {
461: Ox_intr_usr1=0;
462: longjmp(Ox_env,1);
463: }
464:
465: void myhandler(const char *reason,const char *file,int line, int gsl_errno) {
466: cmo *m;
467: FILE *fp;
468: char logname[1024];
1.2 takayama 469: sprintf(logname,"/tmp/ox_python-%d.txt",(int) getpid());
1.1 takayama 470: fp = fopen(logname,"w");
471: fprintf(fp,"%d\n",gsl_errno);
472: fprintf(fp,"%d\n",line);
473: if (file != NULL) fprintf(fp,"%s\n",file); else fprintf(fp,"file?\n");
474: if (reason != NULL) fprintf(fp,"%s\n",reason); else fprintf(fp,"reason?\n");
475: fflush(NULL); fclose(fp);
476: // m = make_error2(reason,file,line,gsl_errno);
477: // send_ox_cmo(fd_rw, m); ox_flush(fd_rw);
478: // send error packet even it is not asked. Todo, OK? --> no
479: restart();
480: }
481: void push_error_from_file() {
482: FILE *fp;
483: #define BUF_SIZE 1024
484: char logname[BUF_SIZE];
1.6 takayama 485: char cmd[BUF_SIZE+256];
1.1 takayama 486: char file[BUF_SIZE];
487: char reason[BUF_SIZE];
488: int gsl_errno, line;
489: cmo *m;
490: fprintf(stderr,"push_error_from_file()\n");
1.2 takayama 491: sprintf(logname,"/tmp/ox_python-%d.txt",(int) getpid());
1.1 takayama 492: fp = fopen(logname,"r");
493: if (fp == NULL) {
494: fprintf(stderr,"open %s is failed\n",logname); return;
495: }
496: fgets(cmd,BUF_SIZE-2,fp); sscanf(cmd,"%d",&gsl_errno);
497: fgets(cmd,BUF_SIZE-2,fp); sscanf(cmd,"%d",&line);
498: #define remove_newline(s) {char *tmp_pos; if ((tmp_pos=strchr(s,'\n')) != NULL) *tmp_pos = '\0';}
499: fgets(file,BUF_SIZE-2,fp); remove_newline(file);
500: fgets(reason,BUF_SIZE-2,fp); remove_newline(reason);
501: fclose(fp);
502: m = make_error2(reason,file,line,gsl_errno);
503: push(m);
504: sprintf(cmd,"rm -f %s",logname);
505: system(cmd);
506: }
507: int main(int argc,char *argv[])
508: {
509: if ( setjmp(Ox_env) ) {
510: fprintf(stderr,"resetting libgsl ...");
511: initialize_stack();
512: if (Ox_intr_usr1) {
513: fprintf(stderr,"and sending OX_SYNC_BALL...");
514: send_ox_tag(fd_rw,OX_SYNC_BALL);
515: }
516: fprintf(stderr,"done\n");
517: Ox_intr_usr1=0;
518: push_error_from_file();
519: }else{
520: ox_stderr_init(stderr);
521: initialize_stack();
522: init_gc();
523: fd_rw = oxf_open(3);
524: oxf_determine_byteorder_server(fd_rw);
525: }
526: #if defined(__CYGWIN__)
527: void *mysignal(int sig,void (*handler)(int m));
528: mysignal(SIGUSR1,usr1_handler);
529: #else
530: signal(SIGUSR1,usr1_handler);
531: #endif
532:
1.2 takayama 533: /* Initialize python */
1.5 takayama 534: Py_SetProgramName((wchar_t *) argv[0]); /* optional but recommended */
1.1 takayama 535: Py_Initialize();
536:
537:
538: while(1) {
539: receive();
540: }
541: Py_Finalize();
542: return(0);
543: }
544:
545: cmo *element_of_at(cmo *list,int k) {
546: int length;
547: static cmo * saved_list = NULL;
548: static cmo **dic;
549: int i;
550: cell *cellp;
551: if (list == NULL) {
552: ox_printf("element_of_at: list is NULL.\n");
553: return( (cmo *)NULL);
554: }
555: if (list->tag != CMO_LIST) {
556: ox_printf("element_of_at: list is not list.\n");
557: return((cmo *)NULL);
558: }
559: length = list_length((cmo_list *)list);
560: if ((k < 0) || (k >= length)) {
561: ox_printf("element_of_at: out of bound length=%d, k=%d.\n",length,k);
562: return((cmo *)NULL);
563: }
564: if (list == saved_list) return(dic[k]);
565: saved_list = list;
566: dic = (cmo **)GC_malloc(sizeof(cmo *)*(length+1));
567: if (dic == NULL) return((cmo *)NULL); // no more memory.
568: cellp = list_first((cmo_list *)list);
569: for (i=0; i<length; i++) {
570: dic[i] = cellp->cmo;
571: cellp = list_next(cellp);
572: }
573: return(dic[k]);
574: }
575:
576: int get_length(cmo *c) {
577: if (c->tag != CMO_LIST) {
578: return(-1);
579: }
580: return(list_length((cmo_list *)c));
581: }
1.2 takayama 582:
583: int my_PyRun_String() {
584: static PyObject *py_main=NULL;
585: static PyObject *py_dict=NULL;
586: PyObject *pyRes;
587: char *cmd;
588: pop(); // pop argc
589: cmd = get_string();
590: if (cmd == NULL) {
591: push(make_error2("my_PyRun_Sring: argument is not a string",NULL,0,-1));
592: return(-1);
593: }
594: printf("cmd=%s\n",cmd);
595: if (py_main == NULL) py_main = PyImport_AddModule("__main__");
596: if (py_dict == NULL) py_dict = PyModule_GetDict(py_main);
1.3 takayama 597: // pyRes = PyRun_String(cmd,Py_single_input,py_dict,py_dict);
1.5 takayama 598: pyRes = PyRun_String(cmd,Py_eval_input,py_dict,py_dict);
1.2 takayama 599: if (pyRes==NULL) {
600: push(make_error2("PyRun_String: exception",NULL,0,-1));
601: PyRun_SimpleString("\n");
602: /* https://stackoverflow.com/questions/12518435/pyrun-string-stop-sending-result-to-stdout-after-any-error
603: */
604: return(-1);
605: }
606: return push_python_result(pyRes);
607: }
608:
609: int push_python_result(PyObject *pyRes) {
1.5 takayama 610: if (PyUnicode_Check(pyRes)) {
611: push((cmo *)new_cmo_string(PyBytes_AsString(PyUnicode_AsEncodedString(pyRes,"UTF-8","strict"))));
1.2 takayama 612: return(0);
1.5 takayama 613: }else if (PyLong_Check(pyRes)) {
614: push((cmo *)new_cmo_int32((int) PyLong_AsLong(pyRes)));
1.2 takayama 615: return(0);
616: }else {
1.5 takayama 617: push((cmo *)new_cmo_string(PyBytes_AsString(PyUnicode_AsEncodedString(PyObject_Str(pyRes),"UTF-8","strict"))));
1.2 takayama 618: return(0);
1.5 takayama 619: /* push((cmo *)new_cmo_string(PyBytes_AsString(PyObject_Str(pyRes))));
620: return(0); */
1.2 takayama 621: // push(make_error2("PyRun_String returns an object which as not been implemented.",NULL,0,-1));
622: // return(-1);
623: }
624: }
625:
626:
627: int my_eval() {
628: static PyObject *pName=NULL;
629: static PyObject *pModule=NULL;
630: static PyObject *pDict=NULL;
631: static PyObject *pFunc=NULL;
632: PyObject *pArgs, *pValue;
633: char *cmd;
634: int i;
635: pop(); // pop argc
636: cmd = get_string();
637: if (cmd == NULL) {
1.3 takayama 638: push(make_error2("my_eval: argument is not a string",NULL,0,-1));
1.2 takayama 639: return(-1);
640: }
641: printf("my_eval cmd=%s\n",cmd);
642:
643: // code from https://docs.python.jp/2.7/extending/embedding.html
1.5 takayama 644: if (pName==NULL) pName = PyBytes_FromString("__builtin__");
1.2 takayama 645: if (pModule==NULL) pModule = PyImport_Import(pName);
646:
647: if (pModule != NULL) {
648: if (pFunc==NULL) pFunc = PyObject_GetAttrString(pModule, "eval");
649: if (pFunc && PyCallable_Check(pFunc)) {
1.3 takayama 650: pArgs = PyTuple_New(3);
1.5 takayama 651: PyTuple_SetItem(pArgs,0,PyBytes_FromString(cmd));
1.3 takayama 652: PyTuple_SetItem(pArgs,1,PyEval_GetGlobals());
653: PyTuple_SetItem(pArgs,2,PyEval_GetLocals());
1.2 takayama 654: pValue = PyObject_CallObject(pFunc, pArgs);
655: Py_DECREF(pArgs);
656: if (pValue != NULL) {
657: push_python_result(pValue);
658: // Py_DECREF(pValue);
659: return(0);
660: }
661: else {
662: PyErr_Print();
663: push(make_error2("Fail to call PyObjedct_CallObject(eval,...)",NULL,0,-1));
664: return(-1);
665: }
666: }
667: else {
668: if (PyErr_Occurred())
669: PyErr_Print();
670: fprintf(stderr, "Cannot find function eval\n");
671: }
672: return(-1);
673: }
674: else {
675: PyErr_Print();
676: fprintf(stderr, "Failed to load __builtin__\n");
677: return -1;
678: }
679: }
1.3 takayama 680:
681: int my_eval2() {
682: static PyObject *pName=NULL;
683: static PyObject *pModule=NULL;
684: static PyObject *pDict=NULL;
685: static PyObject *pFunc=NULL;
686: PyObject *pArgs, *pValue;
687: char *cmd;
688: int i;
689: char *cmd2;
690: pop(); // pop argc
691: cmd = get_string();
692: if (cmd == NULL) {
693: push(make_error2("my_eval2: argument is not a string",NULL,0,-1));
694: return(-1);
695: }
696: printf("my_eval2 cmd=%s\n",cmd);
697:
698: // code from https://stackoverflow.com/questions/48432577/extracting-value-from-python-after-its-embedded-in-c
699: cmd2=(char *)GC_malloc(strlen(cmd)+256);
700: sprintf(cmd2,"f = lambda x: eval(x)");
701: PyRun_SimpleString(cmd2);
702: pModule = PyImport_ImportModule("__main__");
703: pFunc= PyObject_GetAttrString(pModule,"f");
704:
705: if (pModule != NULL) {
706: if (pFunc && PyCallable_Check(pFunc)) {
707: pArgs = PyTuple_New(1);
1.5 takayama 708: PyTuple_SetItem(pArgs,0,PyBytes_FromString(cmd));
1.3 takayama 709: pValue = PyObject_CallObject(pFunc, pArgs);
710: Py_DECREF(pArgs);
711: if (pValue != NULL) {
712: push_python_result(pValue);
713: // Py_DECREF(pValue);
714: return(0);
715: }
716: else {
717: PyErr_Print();
718: push(make_error2("Fail to call PyObjedct_CallObject(eval,...)",NULL,0,-1));
719: return(-1);
720: }
721: }else {
722: if (PyErr_Occurred())
723: PyErr_Print();
724: fprintf(stderr, "Cannot find function f\n");
725: }
726: return(-1);
727: }
728: else {
729: PyErr_Print();
730: fprintf(stderr, "Failed to load __builtin__\n");
731: return -1;
732: }
733: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>