Annotation of OpenXM/src/ox_python/ox_python.c, Revision 1.6
1.6 ! takayama 1: /* $OpenXM: OpenXM/src/ox_python/ox_python.c,v 1.5 2021/12/31 07:43:48 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: }
397: status=PyRun_SimpleString(cmd->s);
398: // push(make_error2("sm_executeStringByLocalParser",NULL,0,-1));
399: push((cmo *)new_cmo_int32(status));
400: return(0);
1.2 takayama 401: /* Todo, set the flag by Py_InspectFlag to avoid exit after exception.
402: See PyRun_SimpleStringFlags, https://docs.python.jp/2.7/c-api/veryhigh.html
403: */
1.1 takayama 404: }
405:
406:
407: int receive_and_execute_sm_command()
408: {
409: int code = receive_int32(fd_rw);
410: switch(code) {
411: case SM_popCMO:
412: sm_popCMO();
413: break;
414: case SM_executeFunction:
415: sm_executeFunction();
416: break;
417: case SM_mathcap:
418: sm_mathcap();
419: break;
420: case SM_setMathCap:
421: pop();
422: break;
423: case SM_executeStringByLocalParser:
424: sm_executeStringByLocalParser();
425: break;
426: default:
427: ;
428: }
429: return(0);
430: }
431:
432: int receive()
433: {
434: int tag;
435:
436: tag = receive_ox_tag(fd_rw);
437: switch(tag) {
438: case OX_DATA:
439: push(receive_cmo(fd_rw));
440: if (Debug) show_stack_top();
441: break;
442: case OX_COMMAND:
443: if (Debug) show_stack_top();
444: receive_and_execute_sm_command();
445: break;
446: default:
447: ;
448: }
449: return 0;
450: }
451:
452: jmp_buf Ox_env;
453: int Ox_intr_usr1=0;
454: void usr1_handler(int sig)
455: {
456: Ox_intr_usr1=1;
457: longjmp(Ox_env,1);
458: }
459: void restart() {
460: Ox_intr_usr1=0;
461: longjmp(Ox_env,1);
462: }
463:
464: void myhandler(const char *reason,const char *file,int line, int gsl_errno) {
465: cmo *m;
466: FILE *fp;
467: char logname[1024];
1.2 takayama 468: sprintf(logname,"/tmp/ox_python-%d.txt",(int) getpid());
1.1 takayama 469: fp = fopen(logname,"w");
470: fprintf(fp,"%d\n",gsl_errno);
471: fprintf(fp,"%d\n",line);
472: if (file != NULL) fprintf(fp,"%s\n",file); else fprintf(fp,"file?\n");
473: if (reason != NULL) fprintf(fp,"%s\n",reason); else fprintf(fp,"reason?\n");
474: fflush(NULL); fclose(fp);
475: // m = make_error2(reason,file,line,gsl_errno);
476: // send_ox_cmo(fd_rw, m); ox_flush(fd_rw);
477: // send error packet even it is not asked. Todo, OK? --> no
478: restart();
479: }
480: void push_error_from_file() {
481: FILE *fp;
482: #define BUF_SIZE 1024
483: char logname[BUF_SIZE];
1.6 ! takayama 484: char cmd[BUF_SIZE+256];
1.1 takayama 485: char file[BUF_SIZE];
486: char reason[BUF_SIZE];
487: int gsl_errno, line;
488: cmo *m;
489: fprintf(stderr,"push_error_from_file()\n");
1.2 takayama 490: sprintf(logname,"/tmp/ox_python-%d.txt",(int) getpid());
1.1 takayama 491: fp = fopen(logname,"r");
492: if (fp == NULL) {
493: fprintf(stderr,"open %s is failed\n",logname); return;
494: }
495: fgets(cmd,BUF_SIZE-2,fp); sscanf(cmd,"%d",&gsl_errno);
496: fgets(cmd,BUF_SIZE-2,fp); sscanf(cmd,"%d",&line);
497: #define remove_newline(s) {char *tmp_pos; if ((tmp_pos=strchr(s,'\n')) != NULL) *tmp_pos = '\0';}
498: fgets(file,BUF_SIZE-2,fp); remove_newline(file);
499: fgets(reason,BUF_SIZE-2,fp); remove_newline(reason);
500: fclose(fp);
501: m = make_error2(reason,file,line,gsl_errno);
502: push(m);
503: sprintf(cmd,"rm -f %s",logname);
504: system(cmd);
505: }
506: int main(int argc,char *argv[])
507: {
508: if ( setjmp(Ox_env) ) {
509: fprintf(stderr,"resetting libgsl ...");
510: initialize_stack();
511: if (Ox_intr_usr1) {
512: fprintf(stderr,"and sending OX_SYNC_BALL...");
513: send_ox_tag(fd_rw,OX_SYNC_BALL);
514: }
515: fprintf(stderr,"done\n");
516: Ox_intr_usr1=0;
517: push_error_from_file();
518: }else{
519: ox_stderr_init(stderr);
520: initialize_stack();
521: init_gc();
522: fd_rw = oxf_open(3);
523: oxf_determine_byteorder_server(fd_rw);
524: }
525: #if defined(__CYGWIN__)
526: void *mysignal(int sig,void (*handler)(int m));
527: mysignal(SIGUSR1,usr1_handler);
528: #else
529: signal(SIGUSR1,usr1_handler);
530: #endif
531:
1.2 takayama 532: /* Initialize python */
1.5 takayama 533: Py_SetProgramName((wchar_t *) argv[0]); /* optional but recommended */
1.1 takayama 534: Py_Initialize();
535:
536:
537: while(1) {
538: receive();
539: }
540: Py_Finalize();
541: return(0);
542: }
543:
544: cmo *element_of_at(cmo *list,int k) {
545: int length;
546: static cmo * saved_list = NULL;
547: static cmo **dic;
548: int i;
549: cell *cellp;
550: if (list == NULL) {
551: ox_printf("element_of_at: list is NULL.\n");
552: return( (cmo *)NULL);
553: }
554: if (list->tag != CMO_LIST) {
555: ox_printf("element_of_at: list is not list.\n");
556: return((cmo *)NULL);
557: }
558: length = list_length((cmo_list *)list);
559: if ((k < 0) || (k >= length)) {
560: ox_printf("element_of_at: out of bound length=%d, k=%d.\n",length,k);
561: return((cmo *)NULL);
562: }
563: if (list == saved_list) return(dic[k]);
564: saved_list = list;
565: dic = (cmo **)GC_malloc(sizeof(cmo *)*(length+1));
566: if (dic == NULL) return((cmo *)NULL); // no more memory.
567: cellp = list_first((cmo_list *)list);
568: for (i=0; i<length; i++) {
569: dic[i] = cellp->cmo;
570: cellp = list_next(cellp);
571: }
572: return(dic[k]);
573: }
574:
575: int get_length(cmo *c) {
576: if (c->tag != CMO_LIST) {
577: return(-1);
578: }
579: return(list_length((cmo_list *)c));
580: }
1.2 takayama 581:
582: int my_PyRun_String() {
583: static PyObject *py_main=NULL;
584: static PyObject *py_dict=NULL;
585: PyObject *pyRes;
586: char *cmd;
587: pop(); // pop argc
588: cmd = get_string();
589: if (cmd == NULL) {
590: push(make_error2("my_PyRun_Sring: argument is not a string",NULL,0,-1));
591: return(-1);
592: }
593: printf("cmd=%s\n",cmd);
594: if (py_main == NULL) py_main = PyImport_AddModule("__main__");
595: if (py_dict == NULL) py_dict = PyModule_GetDict(py_main);
1.3 takayama 596: // pyRes = PyRun_String(cmd,Py_single_input,py_dict,py_dict);
1.5 takayama 597: pyRes = PyRun_String(cmd,Py_eval_input,py_dict,py_dict);
1.2 takayama 598: if (pyRes==NULL) {
599: push(make_error2("PyRun_String: exception",NULL,0,-1));
600: PyRun_SimpleString("\n");
601: /* https://stackoverflow.com/questions/12518435/pyrun-string-stop-sending-result-to-stdout-after-any-error
602: */
603: return(-1);
604: }
605: return push_python_result(pyRes);
606: }
607:
608: int push_python_result(PyObject *pyRes) {
1.5 takayama 609: if (PyUnicode_Check(pyRes)) {
610: push((cmo *)new_cmo_string(PyBytes_AsString(PyUnicode_AsEncodedString(pyRes,"UTF-8","strict"))));
1.2 takayama 611: return(0);
1.5 takayama 612: }else if (PyLong_Check(pyRes)) {
613: push((cmo *)new_cmo_int32((int) PyLong_AsLong(pyRes)));
1.2 takayama 614: return(0);
615: }else {
1.5 takayama 616: push((cmo *)new_cmo_string(PyBytes_AsString(PyUnicode_AsEncodedString(PyObject_Str(pyRes),"UTF-8","strict"))));
1.2 takayama 617: return(0);
1.5 takayama 618: /* push((cmo *)new_cmo_string(PyBytes_AsString(PyObject_Str(pyRes))));
619: return(0); */
1.2 takayama 620: // push(make_error2("PyRun_String returns an object which as not been implemented.",NULL,0,-1));
621: // return(-1);
622: }
623: }
624:
625:
626: int my_eval() {
627: static PyObject *pName=NULL;
628: static PyObject *pModule=NULL;
629: static PyObject *pDict=NULL;
630: static PyObject *pFunc=NULL;
631: PyObject *pArgs, *pValue;
632: char *cmd;
633: int i;
634: pop(); // pop argc
635: cmd = get_string();
636: if (cmd == NULL) {
1.3 takayama 637: push(make_error2("my_eval: argument is not a string",NULL,0,-1));
1.2 takayama 638: return(-1);
639: }
640: printf("my_eval cmd=%s\n",cmd);
641:
642: // code from https://docs.python.jp/2.7/extending/embedding.html
1.5 takayama 643: if (pName==NULL) pName = PyBytes_FromString("__builtin__");
1.2 takayama 644: if (pModule==NULL) pModule = PyImport_Import(pName);
645:
646: if (pModule != NULL) {
647: if (pFunc==NULL) pFunc = PyObject_GetAttrString(pModule, "eval");
648: if (pFunc && PyCallable_Check(pFunc)) {
1.3 takayama 649: pArgs = PyTuple_New(3);
1.5 takayama 650: PyTuple_SetItem(pArgs,0,PyBytes_FromString(cmd));
1.3 takayama 651: PyTuple_SetItem(pArgs,1,PyEval_GetGlobals());
652: PyTuple_SetItem(pArgs,2,PyEval_GetLocals());
1.2 takayama 653: pValue = PyObject_CallObject(pFunc, pArgs);
654: Py_DECREF(pArgs);
655: if (pValue != NULL) {
656: push_python_result(pValue);
657: // Py_DECREF(pValue);
658: return(0);
659: }
660: else {
661: PyErr_Print();
662: push(make_error2("Fail to call PyObjedct_CallObject(eval,...)",NULL,0,-1));
663: return(-1);
664: }
665: }
666: else {
667: if (PyErr_Occurred())
668: PyErr_Print();
669: fprintf(stderr, "Cannot find function eval\n");
670: }
671: return(-1);
672: }
673: else {
674: PyErr_Print();
675: fprintf(stderr, "Failed to load __builtin__\n");
676: return -1;
677: }
678: }
1.3 takayama 679:
680: int my_eval2() {
681: static PyObject *pName=NULL;
682: static PyObject *pModule=NULL;
683: static PyObject *pDict=NULL;
684: static PyObject *pFunc=NULL;
685: PyObject *pArgs, *pValue;
686: char *cmd;
687: int i;
688: char *cmd2;
689: pop(); // pop argc
690: cmd = get_string();
691: if (cmd == NULL) {
692: push(make_error2("my_eval2: argument is not a string",NULL,0,-1));
693: return(-1);
694: }
695: printf("my_eval2 cmd=%s\n",cmd);
696:
697: // code from https://stackoverflow.com/questions/48432577/extracting-value-from-python-after-its-embedded-in-c
698: cmd2=(char *)GC_malloc(strlen(cmd)+256);
699: sprintf(cmd2,"f = lambda x: eval(x)");
700: PyRun_SimpleString(cmd2);
701: pModule = PyImport_ImportModule("__main__");
702: pFunc= PyObject_GetAttrString(pModule,"f");
703:
704: if (pModule != NULL) {
705: if (pFunc && PyCallable_Check(pFunc)) {
706: pArgs = PyTuple_New(1);
1.5 takayama 707: PyTuple_SetItem(pArgs,0,PyBytes_FromString(cmd));
1.3 takayama 708: pValue = PyObject_CallObject(pFunc, pArgs);
709: Py_DECREF(pArgs);
710: if (pValue != NULL) {
711: push_python_result(pValue);
712: // Py_DECREF(pValue);
713: return(0);
714: }
715: else {
716: PyErr_Print();
717: push(make_error2("Fail to call PyObjedct_CallObject(eval,...)",NULL,0,-1));
718: return(-1);
719: }
720: }else {
721: if (PyErr_Occurred())
722: PyErr_Print();
723: fprintf(stderr, "Cannot find function f\n");
724: }
725: return(-1);
726: }
727: else {
728: PyErr_Print();
729: fprintf(stderr, "Failed to load __builtin__\n");
730: return -1;
731: }
732: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>