Annotation of OpenXM/src/ox_python/ox_python.c, Revision 1.1
1.1 ! takayama 1: /* $OpenXM$
! 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;
! 155: n = 5;
! 156: argv = (cmo **) GC_malloc(sizeof(cmo *)*n);
! 157: ms = (cmo *)new_cmo_string("Error"); argv[0] = ms;
! 158: if (reason != NULL) {s = (char *)GC_malloc(strlen(reason)+1); strcpy(s,reason);
! 159: }else strcpy(s,"");
! 160: ms = (cmo *) new_cmo_string(s); argv[1] = ms;
! 161: if (fname != NULL) {s = (char *)GC_malloc(strlen(fname)+1); strcpy(s,fname);
! 162: }else strcpy(s,"");
! 163: ms = (cmo *) new_cmo_string(s); argv[2] = ms;
! 164: err = (cmo *)new_cmo_int32(line); argv[3] = err;
! 165: err = (cmo *)new_cmo_int32(code); argv[4] = err;
! 166:
! 167: m = (cmo *)new_cmo_list_array((void *)argv,n);
! 168: return (m);
! 169: }
! 170:
! 171: int get_i()
! 172: {
! 173: cmo *c = pop();
! 174: if (c->tag == CMO_INT32) {
! 175: return ((cmo_int32 *)c)->i;
! 176: }else if (c->tag == CMO_ZZ) {
! 177: return mpz_get_si(((cmo_zz *)c)->mpz);
! 178: }else if (c->tag == CMO_NULL) {
! 179: return(0);
! 180: }else if (c->tag == CMO_ZERO) {
! 181: return(0);
! 182: }
! 183: myhandler("get_i: not an integer",NULL,0,-1);
! 184: return 0;
! 185: }
! 186:
! 187: void get_xy(int *x, int *y)
! 188: {
! 189: pop();
! 190: *x = get_i();
! 191: *y = get_i();
! 192: }
! 193:
! 194: void my_add_int32()
! 195: {
! 196: int x, y;
! 197: get_xy(&x, &y);
! 198: push((cmo *)new_cmo_int32(x+y));
! 199: }
! 200:
! 201: double get_double()
! 202: {
! 203: #define mympz(c) (((cmo_zz *)c)->mpz)
! 204: cmo *c = pop();
! 205: if (c->tag == CMO_INT32) {
! 206: return( (double) (((cmo_int32 *)c)->i) );
! 207: }else if (c->tag == CMO_IEEE_DOUBLE_FLOAT) {
! 208: return (((cmo_double *)c)->d); // see ox_toolkit.h
! 209: }else if (c->tag == CMO_ZZ) {
! 210: if ((mpz_cmp_si(mympz(c),(long int) 0x7fffffff)>0) ||
! 211: (mpz_cmp_si(mympz(c),(long int) -0x7fffffff)<0)) {
! 212: myhandler("get_double: out of int32",NULL,0,-1);
! 213: return(NAN);
! 214: }
! 215: return( (double) mpz_get_si(((cmo_zz *)c)->mpz));
! 216: }else if (c->tag == CMO_NULL) {
! 217: return(0);
! 218: }else if (c->tag == CMO_ZERO) {
! 219: return(0);
! 220: }
! 221: myhandler("get_double: not a double",NULL,0,-1);
! 222: return(NAN);
! 223: }
! 224: /* get_double() will be obsolted and will be replaced by cmo2double(c) */
! 225: double cmo2double(cmo *c)
! 226: {
! 227: #define mympz(c) (((cmo_zz *)c)->mpz)
! 228: if (c == NULL) c = pop();
! 229: if (c->tag == CMO_INT32) {
! 230: return( (double) (((cmo_int32 *)c)->i) );
! 231: }else if (c->tag == CMO_IEEE_DOUBLE_FLOAT) {
! 232: return (((cmo_double *)c)->d); // see ox_toolkit.h
! 233: }else if (c->tag == CMO_ZZ) {
! 234: if ((mpz_cmp_si(mympz(c),(long int) 0x7fffffff)>0) ||
! 235: (mpz_cmp_si(mympz(c),(long int) -0x7fffffff)<0)) {
! 236: myhandler("get_double: out of int32",NULL,0,-1);
! 237: return(NAN);
! 238: }
! 239: return( (double) mpz_get_si(((cmo_zz *)c)->mpz));
! 240: }else if (c->tag == CMO_NULL) {
! 241: return(0);
! 242: }else if (c->tag == CMO_ZERO) {
! 243: return(0);
! 244: }
! 245: myhandler("cmo2double: not a double",NULL,0,-1);
! 246: return(NAN);
! 247: }
! 248:
! 249: void my_add_double() {
! 250: double x,y;
! 251: pop();
! 252: y = get_double();
! 253: x = get_double();
! 254: push((cmo *)new_cmo_double(x+y));
! 255: }
! 256:
! 257: double *get_double_list(int *length) {
! 258: cmo *c;
! 259: cmo *entry;
! 260: cell *cellp;
! 261: double *d;
! 262: int n,i;
! 263: c = pop();
! 264: if (c->tag != CMO_LIST) {
! 265: // make_error2("get_double_list",NULL,0,-1);
! 266: *length=-1; return(0);
! 267: }
! 268: n = *length = list_length((cmo_list *)c);
! 269: d = (double *) GC_malloc(sizeof(double)*(*length+1));
! 270: cellp = list_first((cmo_list *)c);
! 271: entry = cellp->cmo;
! 272: for (i=0; i<n; i++) {
! 273: if (Debug) {
! 274: printf("entry[%d]=",i); print_cmo(entry); printf("\n");
! 275: }
! 276: if (entry->tag == CMO_INT32) {
! 277: d[i]=( (double) (((cmo_int32 *)entry)->i) );
! 278: }else if (entry->tag == CMO_IEEE_DOUBLE_FLOAT) {
! 279: d[i]=((cmo_double *)entry)->d;
! 280: }else if (entry->tag == CMO_ZZ) {
! 281: d[i]=( (double) mpz_get_si(((cmo_zz *)entry)->mpz));
! 282: }else if (entry->tag == CMO_NULL) {
! 283: d[i]= 0;
! 284: }else {
! 285: fprintf(stderr,"entries of the list should be int32 or zz or double\n");
! 286: *length = -1;
! 287: myhandler("get_double_list",NULL,0,-1);
! 288: return(NULL);
! 289: }
! 290: cellp = list_next(cellp);
! 291: entry = cellp->cmo;
! 292: }
! 293: return(d);
! 294: }
! 295: /* get_double_list will be obsolted and will be replaced by cmo2double_list() */
! 296: double *cmo2double_list(int *length,cmo *c) {
! 297: cmo *entry;
! 298: cell *cellp;
! 299: double *d;
! 300: int n,i;
! 301: if (c == NULL) c = pop();
! 302: if (c->tag != CMO_LIST) {
! 303: // make_error2("get_double_list",NULL,0,-1);
! 304: *length=-1; return(0);
! 305: }
! 306: n = *length = list_length((cmo_list *)c);
! 307: d = (double *) GC_malloc(sizeof(double)*(*length+1));
! 308: cellp = list_first((cmo_list *)c);
! 309: entry = cellp->cmo;
! 310: for (i=0; i<n; i++) {
! 311: if (Debug) {
! 312: printf("entry[%d]=",i); print_cmo(entry); printf("\n");
! 313: }
! 314: if (entry->tag == CMO_INT32) {
! 315: d[i]=( (double) (((cmo_int32 *)entry)->i) );
! 316: }else if (entry->tag == CMO_IEEE_DOUBLE_FLOAT) {
! 317: d[i]=((cmo_double *)entry)->d;
! 318: }else if (entry->tag == CMO_ZZ) {
! 319: d[i]=( (double) mpz_get_si(((cmo_zz *)entry)->mpz));
! 320: }else if (entry->tag == CMO_NULL) {
! 321: d[i]= 0;
! 322: }else {
! 323: fprintf(stderr,"entries of the list should be int32 or zz or double\n");
! 324: *length = -1;
! 325: myhandler("get_double_list",NULL,0,-1);
! 326: return(NULL);
! 327: }
! 328: cellp = list_next(cellp);
! 329: entry = cellp->cmo;
! 330: }
! 331: return(d);
! 332: }
! 333: void show_double_list() {
! 334: int n;
! 335: double *d;
! 336: int i;
! 337: pop(); // pop argument number;
! 338: d = get_double_list(&n);
! 339: if (n < 0) fprintf(stderr,"Error in the double list\n");
! 340: printf("show_double_list: length=%d\n",n);
! 341: for (i=0; i<n; i++) {
! 342: printf("%lg, ",d[i]);
! 343: }
! 344: printf("\n");
! 345: }
! 346:
! 347: char *get_string() {
! 348: cmo *c;
! 349: c = pop();
! 350: if (c->tag == CMO_STRING) {
! 351: return (((cmo_string *)c)->s);
! 352: }
! 353: // make_error2(-1);
! 354: return(NULL);
! 355: }
! 356:
! 357:
! 358: int sm_executeFunction()
! 359: {
! 360: cmo_string *func = (cmo_string *)pop();
! 361: if (func->tag != CMO_STRING) {
! 362: push(make_error2("sm_executeFunction, not CMO_STRING",NULL,0,-1));
! 363: return -1;
! 364: }
! 365: // Test functions
! 366: if (strcmp(func->s, "add_int32") == 0) {
! 367: my_add_int32();
! 368: }else if (strcmp(func->s,"add_double")==0) {
! 369: my_add_double();
! 370: }else if (strcmp(func->s,"show_double_list")==0) {
! 371: show_double_list();
! 372: }else if (strcmp(func->s,"restart")==0) {
! 373: pop(); restart();
! 374: }else {
! 375: push(make_error2("sm_executeFunction, unknown function",NULL,0,-1));
! 376: return -1;
! 377: }
! 378: return(0);
! 379: }
! 380:
! 381: int sm_executeStringByLocalParser()
! 382: {
! 383: int status;
! 384: cmo_string *cmd = (cmo_string *)pop();
! 385: if (cmd->tag != CMO_STRING) {
! 386: push(make_error2("sm_executeStringByLocalParser, not CMO_STRING",NULL,0,-1));
! 387: return -1;
! 388: }
! 389: status=PyRun_SimpleString(cmd->s);
! 390: // push(make_error2("sm_executeStringByLocalParser",NULL,0,-1));
! 391: push((cmo *)new_cmo_int32(status));
! 392: return(0);
! 393: }
! 394:
! 395:
! 396: int receive_and_execute_sm_command()
! 397: {
! 398: int code = receive_int32(fd_rw);
! 399: switch(code) {
! 400: case SM_popCMO:
! 401: sm_popCMO();
! 402: break;
! 403: case SM_executeFunction:
! 404: sm_executeFunction();
! 405: break;
! 406: case SM_mathcap:
! 407: sm_mathcap();
! 408: break;
! 409: case SM_setMathCap:
! 410: pop();
! 411: break;
! 412: case SM_executeStringByLocalParser:
! 413: sm_executeStringByLocalParser();
! 414: break;
! 415: default:
! 416: ;
! 417: }
! 418: return(0);
! 419: }
! 420:
! 421: int receive()
! 422: {
! 423: int tag;
! 424:
! 425: tag = receive_ox_tag(fd_rw);
! 426: switch(tag) {
! 427: case OX_DATA:
! 428: push(receive_cmo(fd_rw));
! 429: if (Debug) show_stack_top();
! 430: break;
! 431: case OX_COMMAND:
! 432: if (Debug) show_stack_top();
! 433: receive_and_execute_sm_command();
! 434: break;
! 435: default:
! 436: ;
! 437: }
! 438: return 0;
! 439: }
! 440:
! 441: jmp_buf Ox_env;
! 442: int Ox_intr_usr1=0;
! 443: void usr1_handler(int sig)
! 444: {
! 445: Ox_intr_usr1=1;
! 446: longjmp(Ox_env,1);
! 447: }
! 448: void restart() {
! 449: Ox_intr_usr1=0;
! 450: longjmp(Ox_env,1);
! 451: }
! 452:
! 453: void myhandler(const char *reason,const char *file,int line, int gsl_errno) {
! 454: cmo *m;
! 455: FILE *fp;
! 456: char logname[1024];
! 457: sprintf(logname,"/tmp/ox_gsl-%d.txt",(int) getpid());
! 458: fp = fopen(logname,"w");
! 459: fprintf(fp,"%d\n",gsl_errno);
! 460: fprintf(fp,"%d\n",line);
! 461: if (file != NULL) fprintf(fp,"%s\n",file); else fprintf(fp,"file?\n");
! 462: if (reason != NULL) fprintf(fp,"%s\n",reason); else fprintf(fp,"reason?\n");
! 463: fflush(NULL); fclose(fp);
! 464: // m = make_error2(reason,file,line,gsl_errno);
! 465: // send_ox_cmo(fd_rw, m); ox_flush(fd_rw);
! 466: // send error packet even it is not asked. Todo, OK? --> no
! 467: restart();
! 468: }
! 469: void push_error_from_file() {
! 470: FILE *fp;
! 471: #define BUF_SIZE 1024
! 472: char logname[BUF_SIZE];
! 473: char cmd[BUF_SIZE];
! 474: char file[BUF_SIZE];
! 475: char reason[BUF_SIZE];
! 476: int gsl_errno, line;
! 477: cmo *m;
! 478: fprintf(stderr,"push_error_from_file()\n");
! 479: sprintf(logname,"/tmp/ox_gsl-%d.txt",(int) getpid());
! 480: fp = fopen(logname,"r");
! 481: if (fp == NULL) {
! 482: fprintf(stderr,"open %s is failed\n",logname); return;
! 483: }
! 484: fgets(cmd,BUF_SIZE-2,fp); sscanf(cmd,"%d",&gsl_errno);
! 485: fgets(cmd,BUF_SIZE-2,fp); sscanf(cmd,"%d",&line);
! 486: #define remove_newline(s) {char *tmp_pos; if ((tmp_pos=strchr(s,'\n')) != NULL) *tmp_pos = '\0';}
! 487: fgets(file,BUF_SIZE-2,fp); remove_newline(file);
! 488: fgets(reason,BUF_SIZE-2,fp); remove_newline(reason);
! 489: fclose(fp);
! 490: m = make_error2(reason,file,line,gsl_errno);
! 491: push(m);
! 492: sprintf(cmd,"rm -f %s",logname);
! 493: system(cmd);
! 494: }
! 495: int main(int argc,char *argv[])
! 496: {
! 497: if ( setjmp(Ox_env) ) {
! 498: fprintf(stderr,"resetting libgsl ...");
! 499: initialize_stack();
! 500: if (Ox_intr_usr1) {
! 501: fprintf(stderr,"and sending OX_SYNC_BALL...");
! 502: send_ox_tag(fd_rw,OX_SYNC_BALL);
! 503: }
! 504: fprintf(stderr,"done\n");
! 505: Ox_intr_usr1=0;
! 506: push_error_from_file();
! 507: }else{
! 508: ox_stderr_init(stderr);
! 509: initialize_stack();
! 510: init_gc();
! 511: fd_rw = oxf_open(3);
! 512: oxf_determine_byteorder_server(fd_rw);
! 513: }
! 514: #if defined(__CYGWIN__)
! 515: void *mysignal(int sig,void (*handler)(int m));
! 516: mysignal(SIGUSR1,usr1_handler);
! 517: #else
! 518: signal(SIGUSR1,usr1_handler);
! 519: #endif
! 520:
! 521: /* try python */
! 522: Py_SetProgramName(argv[0]); /* optional but recommended */
! 523: Py_Initialize();
! 524: /* end of try pythong */
! 525:
! 526:
! 527: while(1) {
! 528: receive();
! 529: }
! 530: Py_Finalize();
! 531: return(0);
! 532: }
! 533:
! 534: cmo *element_of_at(cmo *list,int k) {
! 535: int length;
! 536: static cmo * saved_list = NULL;
! 537: static cmo **dic;
! 538: int i;
! 539: cell *cellp;
! 540: if (list == NULL) {
! 541: ox_printf("element_of_at: list is NULL.\n");
! 542: return( (cmo *)NULL);
! 543: }
! 544: if (list->tag != CMO_LIST) {
! 545: ox_printf("element_of_at: list is not list.\n");
! 546: return((cmo *)NULL);
! 547: }
! 548: length = list_length((cmo_list *)list);
! 549: if ((k < 0) || (k >= length)) {
! 550: ox_printf("element_of_at: out of bound length=%d, k=%d.\n",length,k);
! 551: return((cmo *)NULL);
! 552: }
! 553: if (list == saved_list) return(dic[k]);
! 554: saved_list = list;
! 555: dic = (cmo **)GC_malloc(sizeof(cmo *)*(length+1));
! 556: if (dic == NULL) return((cmo *)NULL); // no more memory.
! 557: cellp = list_first((cmo_list *)list);
! 558: for (i=0; i<length; i++) {
! 559: dic[i] = cellp->cmo;
! 560: cellp = list_next(cellp);
! 561: }
! 562: return(dic[k]);
! 563: }
! 564:
! 565: int get_length(cmo *c) {
! 566: if (c->tag != CMO_LIST) {
! 567: return(-1);
! 568: }
! 569: return(list_length((cmo_list *)c));
! 570: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>