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

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>