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

Annotation of OpenXM/src/kan96xx/Kan/shell.c, Revision 1.4

1.4     ! takayama    1: /* $OpenXM: OpenXM/src/kan96xx/Kan/shell.c,v 1.3 2003/12/03 09:00:46 takayama Exp $ */
1.1       takayama    2: #include <stdio.h>
                      3: #include <sys/types.h>
                      4: #include <sys/stat.h>
                      5: #include <fcntl.h>
                      6: #include <stdlib.h>
                      7: #include <unistd.h>
                      8: #include <sys/wait.h>
                      9: #include "datatype.h"
                     10: #include "stackm.h"
                     11: #include "extern.h"
                     12: #include "extern2.h"
                     13: #include <signal.h>
                     14: #include "plugin.h"
                     15: #include "kclass.h"
                     16: #include <ctype.h>
                     17: #include "ox_pathfinder.h"
                     18:
1.2       takayama   19: static struct object KoxShell_test1(struct object ob);
1.3       takayama   20: static struct object oxsExecuteBlocked(struct object ob);
                     21: static struct object oxsSetenv(struct object ob);
                     22: static char *oxsIsURI(char *s);
                     23: static char *oxsURIgetVarName(char *s);
                     24: static char *oxsURIgetExtension(char *s);
                     25: static char *oxsVarToFile(char *v,char *extension,char *comamnd,int tmp);
                     26: static int oxsFileToVar(char *v,char *fname);
                     27: static char **oxsBuildArgv(struct object ob);
                     28: static struct object testmain(struct object ob);
                     29:
                     30: #define mymalloc(n)  sGC_malloc(n)
                     31: #define nomemory(n)  errorKan1("%s\n","No more memory in shell.c");
                     32:
                     33: #define MAXFILES  256
                     34: static char *AfterReadFile[MAXFILES];
                     35: static char *AfterSetVar[MAXFILES];
                     36: static int AfterPt=0;
                     37: static char *AfterDeleteFile[MAXFILES];
                     38: static int AfterD=0;
1.2       takayama   39:
                     40: struct object KoxShell(struct object ob) {
                     41:   return KoxShell_test1(ob);
                     42: }
                     43:
1.3       takayama   44: /* A temporary help system */
                     45: void KoxShellHelp(char *key,FILE *fp) {
                     46:   char *keys[]={"command","export","which","@@@@gatekeeper"};
                     47:   int i;
                     48: #define HSIZE 20
                     49:   char *s[HSIZE];
                     50:   if (key == NULL) {
                     51:     for (i=0; strcmp(keys[i],"@@@@gatekeeper") != 0; i++) {
                     52:          fprintf(fp,"%s\n",keys[i]);
                     53:          KoxShellHelp(keys[i],fp);
                     54:          fprintf(fp,"\n",keys[i]);
                     55:        }
                     56:        return;
                     57:   }
                     58:   for (i=0; i<HSIZE; i++) s[i] = NULL;
                     59:   if (strcmp(key,"export")==0) {
                     60:        s[0] = "export env_name  =  value";
                     61:        s[1] = "export env_name = ";
                     62:        s[2] = "Example: [(export) (PATH) (=) (/usr/new/bin:${PATH})] oxshell";
                     63:        s[3] = NULL;
                     64:   }else if (strcmp(key,"which")==0) {
                     65:        s[0] = "which cmd_name";
                     66:        s[1] = "which cmd_name path";
                     67:        s[2] = "Example: [(which) (ls)] oxshell";
                     68:     s[3] = NULL;
                     69:   }else if (strcmp(key,"command")==0) {
                     70:        s[0] = "Executing a command";
                     71:        s[1] = "cmdname arg1 arg2 ... ";
                     72:        s[2] = "Example 1: /afo (Hello! ) def [(cat) (stringIn://afo)] oxshell";
                     73:        s[3] = "Example 2: [(polymake) (stringInOut://afo.poly) (FACETS)] oxshell";
                     74:     s[4] = NULL;
                     75:   }else{
                     76:   }
                     77:   i = 0;
                     78:   while (s[i] != NULL) {
                     79:        fprintf(fp,"%s\n",s[i++]);
                     80:   }
                     81: }
                     82:
                     83:
1.2       takayama   84: static struct object KoxShell_test1(struct object ob) {
                     85:   /* A simple shell. It does not implement a parser. */
                     86:   struct object rob;
                     87:   char *cmd;
                     88:   char *arg1,*arg2;
                     89:   int i,n;
                     90:   rob = NullObject; cmd = NULL; arg1=NULL; arg2=NULL;
                     91:   if (ob.tag != Sarray) errorKan1("%s\n","KoxShell requires an array as an argument.");
                     92:   n = getoaSize(ob);
                     93:   for (i=0; i<n; i++) {
                     94:        if (getoa(ob,i).tag != Sdollar) errorKan1("%s\n","KoxShell requires an array of string as an argument.");
                     95:   }
                     96:
                     97:   if (n == 0) return(rob);
                     98:   cmd = KopString(getoa(ob,0));
1.3       takayama   99:   if (strcmp(cmd,"testmain")==0) {
                    100:     rob = testmain(ob);
                    101:   }else if (strcmp(cmd,"which")==0) {
1.2       takayama  102:        if (n == 2) {
                    103:          rob = KoxWhich(getoa(ob,1),KpoInteger(0));
                    104:        }else if (n==3) {
                    105:          rob = KoxWhich(getoa(ob,1),getoa(ob,2));
                    106:        }else{
                    107:          errorKan1("%s\n","shell: << which command-name >> or << which command-name path >>");
                    108:        }
                    109:        return(rob);
                    110:   }else if (strcmp(cmd,"export")==0) {
1.3       takayama  111:        rob=oxsSetenv(ob);
1.2       takayama  112:   }else{
1.3       takayama  113:        rob = oxsExecuteBlocked(ob);
1.2       takayama  114:   }
                    115:   return(rob);
                    116: }
1.1       takayama  117:
                    118: /* Functions for ox_shell */
                    119: struct object KoxWhich(struct object cmdo,struct object patho) {
                    120:   struct object rob;
                    121:   char *sss;
                    122:   rob = NullObject;
                    123:   if (cmdo.tag != Sdollar) errorKan1("%s\n","KoxWhich(str-obj,str-obj)");
                    124:   if (patho.tag == Sdollar) {
                    125:     sss=oxWhich(KopString(cmdo),KopString(patho));
                    126:     if (sss != NULL) rob=KpoString(sss);
                    127:     else{
                    128:       sss=getCommandPath(KopString(cmdo));
                    129:       if (sss != NULL) rob=KpoString(sss);
                    130:     }
                    131:   }else{
                    132:     sss=getCommandPath(KopString(cmdo));
                    133:     if (sss != NULL) rob=KpoString(sss);
                    134:   }
                    135:   return(rob);
                    136: }
                    137:
1.3       takayama  138: /* Example. [(export)  (PATH)  (=)  (/usr/new/bin:$PATH)] */
                    139: static struct object oxsSetenv(struct object ob) {
                    140:   struct object rob;
                    141:   int i,n;
                    142:   char *envp;
                    143:   char *new;
                    144:   int r;
                    145:   rob = NullObject;
                    146:   if (ob.tag != Sarray) errorKan1("%s\n","oxsSetenv requires an array of srings.");
                    147:   n = getoaSize(ob);
                    148:   if ((n != 4) && (n != 3)) errorKan1("%s\n","oxsSetenv requires an array of srings. Length must be 3 or 4.");
                    149:   for (i=0; i<n; i++) {
                    150:        if (getoa(ob,i).tag != Sdollar) errorKan1("%s\n","oxsSetenv requires an array of srings. Length must be 3 or 4.");
                    151:   }
                    152:
                    153:   if (strcmp(KopString(getoa(ob,2)),"=") != 0) {
                    154:        errorKan1("%s\n","oxsSetenv, example [(export)  (PATH)  (=)  (/usr/new/bin:$PATH)] oxshell");
                    155:   }
                    156:   envp = KopString(getoa(ob,1));
                    157:   if (n == 4) {
                    158:        new = KopString(getoa(ob,3));
                    159:        /* printf("%s\n",new); */
                    160:        new = oxEvalEnvVar(new);
                    161:        /* printf("%s\n",new); */
                    162:        r = setenv(envp,new,1);
                    163:   }else{
                    164:        unsetenv(envp); r = 0;
                    165:   }
                    166:   if (r != 0) errorKan1("%s\n","setenv failed.");
                    167:   new = (char *) getenv(envp);
                    168:   if (new != NULL) {
                    169:        rob = KpoString((char *) getenv(envp));
                    170:   }
                    171:   return(rob);
                    172: }
                    173:
                    174: /* s="stringIn://abc.poly"   ==> stringIn
                    175:    s="stringInOut://abc.poly" ==> stringInOut
                    176: */
                    177: char *oxsIsURI(char *s) {
                    178:   int n,i,j;
                    179:   char *u;
                    180:   if (s == NULL) return((char *)NULL);
                    181:   n = strlen(s);
                    182:   for (i=0; i<n-3;i++) {
                    183:     if ((s[i] == ':') && (s[i+1] == '/') && (s[i+2] == '/')) {
                    184:       u = (char *) mymalloc(i+1);
                    185:       if (u == NULL) nomemory(1);
                    186:       u[0]=0;
                    187:       for (j=0; j<i; j++) {
                    188:         u[j] = s[j]; u[j+1]=0;
                    189:       }
                    190:       return(u);
                    191:     }
                    192:   }
                    193:   return(NULL);
                    194: }
1.1       takayama  195:
1.3       takayama  196: /* s="stringIn://abc.poly"   ==> abc
                    197:    s="stringInOut://abc.poly" ==> abc
                    198:    s="stringInOut://abc" ==> abc
                    199: */
                    200: char *oxsURIgetVarName(char *s) {
                    201:   int n,i,j;
                    202:   char *u;
                    203:   if (s == NULL) return((char *)NULL);
                    204:   n = strlen(s);
                    205:   for (i=0; i<n-3;i++) {
                    206:     if ((s[i] == ':') && (s[i+1] == '/') && (s[i+2] == '/')) {
                    207:       u = (char *) mymalloc(n-i+1);
                    208:       if (u == NULL) nomemory(1);
                    209:       u[0]=0;
                    210:       for (j=i+3; j<n; j++) {
                    211:         if (s[j] == '.') break;
                    212:         u[j-i-3] = s[j]; u[j-i-3+1]=0;
                    213:       }
                    214:       return(u);
                    215:     }
                    216:   }
                    217:   return(NULL);
                    218: }
                    219:
                    220: /* s="stringIn://abc.poly"   ==> poly
                    221:    s="stringInOut://abc.poly" ==> poly
                    222:    s="stringInOut://abc" ==> NULL
                    223: */
                    224: char *oxsURIgetExtension(char *s) {
                    225:   int n,i,j,k;
                    226:   char *u;
                    227:   if (s == NULL) return((char *)NULL);
                    228:   n = strlen(s);
                    229:   for (i=0; i<n-3;i++) {
                    230:     if ((s[i] == ':') && (s[i+1] == '/') && (s[i+2] == '/')) {
                    231:       for (j=i+3; j<n; j++) {
                    232:         if (s[j] == '.') {
                    233:           u = (char *) mymalloc(n-j+2);
                    234:           if (u == NULL) nomemory(1);
                    235:           u[0]=0;
                    236:           for (k=j+1; k<n; k++) {
                    237:             u[k-j-1] = s[k]; u[k-j] = 0;
                    238:           }
                    239:           return(u);
                    240:         }
                    241:       }
                    242:     }
                    243:   }
                    244:   return(NULL);
                    245: }
                    246:
                    247: static struct object testmain(struct object ob) {
                    248:   struct object rob;
                    249:   char *s;
                    250:   struct object ot;
                    251:   char **av;
                    252:   int i;
                    253:   rob = NullObject;
                    254:
                    255:   /* Try  sm1 -s " /hoge (hogehoge) def [(testmain)] oxshell afo message " */
                    256:
                    257:   ot = newObjectArray(3);
                    258:   getoa(ot,0)=KpoString("cat");
                    259:   getoa(ot,1)=KpoString("stringInOut://hoge.poly");
                    260:   getoa(ot,2)=KpoString("${HOME}/t.t");
                    261:   av=oxsBuildArgv(ot);
                    262:   for (i=0; av[i] != NULL; i++) {
                    263:        printf("%s\n",av[i]);
                    264:   }
                    265:   printf("------------------------------\n");
                    266:
                    267:   s=oxsVarToFile("hoge","poly","polymake",0);
                    268:   printf("%s\n",s);
                    269:   oxsFileToVar("afo",s);
                    270:   return(rob);
                    271: }
                    272:
                    273: char *oxsVarToFile(char *v,char *ext,char *command,int usetmp) {
                    274:   char *fname;
                    275:   int winname;
                    276:   FILE *fp;
                    277:   int n,i,prevc,c;
                    278:   char *prog;
                    279:   struct object vv;
                    280:
                    281:   /*bug; winname must be automatically set by looking at command.
                    282:     If command is win32-native-application, then winname=1; else winname=0.
                    283:     For example, if command=="gnuplot32" then winmame=1; else winname=0;
                    284:   */
                    285:   winname = 0;
                    286:
                    287:   fname = generateTMPfileName2(v,ext,usetmp,winname);
                    288:   if (fname == NULL) errorKan1("%s\n","generateTMPfileName2() is failed.");
                    289:   if (v == NULL) errorKan1("%s\n","oxsVarToFile(), v is NULL.");
                    290:   vv = KfindUserDictionary(v);
                    291:   if (vv.tag != Sdollar) errorKan1("%s\n","oxsVarToFile(), value is not a string object or the object is not found in the dictionary.");
                    292:   prog = KopString(vv);
                    293:
                    294:   fp = fopen(fname,"w");
                    295:   if (fp == NULL) errorKan1("%s\n","oxsVarToFile(), fail to open a file.");
                    296:   n = strlen(prog);
                    297:   prevc = 0;
                    298:   for (i=0; i<n ; i++) {
                    299:        c = prog[i];
                    300:        if (winname) {
                    301:          if ((c == '\n') && (prevc != 0xd)) {
                    302:                fputc(0xd,fp); fputc(c,fp);
                    303:          }
                    304:        }else{
                    305:          fputc(c,fp);
                    306:        }
                    307:        prevc = c;
                    308:   }
                    309:   if (fclose(fp) != 0) errorKan1("%s\n","oxsVarToFile(), fail to close the file.");
                    310:
                    311:   return(fname);
                    312: }
                    313:
                    314: int oxsFileToVar(char *v,char *fname) {
                    315:   FILE *fp;
                    316:   char *s, *sold;
                    317:   int limit;
                    318:   int c,i;
                    319:
                    320:   if (v == NULL) errorKan1("%s\n","oxsFileToVar(), v is NULL.");
                    321:   limit = 1024;
                    322:   fp = fopen(fname,"r");
                    323:   if (fp == NULL) {
                    324:        fprintf(stderr,"Filename=%s\n",fname);
                    325:        errorKan1("%s\n","oxsFileToVar(), the file cannot be opened.");
                    326:   }
                    327:   s = (char *)mymalloc(limit);
                    328:   if (s == NULL) errorKan1("%s\n","No more memory in oxsFileToVar().");
                    329:
                    330:   i = 0;
                    331:   while ((c=fgetc(fp)) != EOF) {
                    332:        s[i] = c; s[i+1] = 0;
                    333:        if (i > limit - 10) {
                    334:          sold = s; limit *= 2;
                    335:          s = (char *)mymalloc(limit);
                    336:          if (s == NULL) errorKan1("%s\n","No more memory in oxsFileToVar().");
                    337:          strcpy(s,sold);
                    338:        }
                    339:     i++;
                    340:   }
                    341:   fclose(fp);
                    342:
                    343:   KputUserDictionary(v,KpoString(s));
                    344:   return(0);
                    345: }
                    346:
                    347: static char **oxsBuildArgv(struct object ob) {
                    348:   int n,i;
                    349:   char **argv;
                    350:   char *s;
                    351:   char *type;
                    352:   char *ext, *v;
                    353:   int usetmp=1;
                    354:   int win=0;
1.4     ! takayama  355:   struct object ocmd;
1.3       takayama  356:
                    357:   /* bug: win variable must be properly set on windows native. */
                    358:
                    359:   if (ob.tag != Sarray) errorKan1("%s\n","oxsBuildArgv() requires an array as an argument.");
                    360:   n = getoaSize(ob);
                    361:   for (i=0; i<n; i++) {
                    362:        if (getoa(ob,i).tag != Sdollar) errorKan1("%s\n","oxsBuildArgv() requires an array of string as an argument.");
                    363:   }
                    364:
                    365:   argv = (char **) mymalloc(sizeof(char *)*(n+2));
                    366:   argv[0] = (char *)NULL;
                    367:   if (n == 0) return(argv);
                    368:
                    369:   s = KopString(getoa(ob,0));
                    370:   s = oxEvalEnvVar(s);
1.4     ! takayama  371:   ocmd = KoxWhich(KpoString(s),KpoInteger(0));
        !           372:   if (ocmd.tag != Sdollar) {
        !           373:        argv[0] = NULL;
        !           374:   }else{
        !           375:        argv[0] = KopString(ocmd);
        !           376:   }
1.3       takayama  377:   argv[1] = (char *)NULL;
                    378:   if (argv[0] == NULL) {
                    379:        fprintf(stderr,"cmdname=%s\n",s);
                    380:        errorKan1("%s\n","oxsBuildArgv() Command is not found.\n");
                    381:   }
                    382:   for (i=1; i<n; i++) {
                    383:        argv[i] = argv[i+1] = NULL;
                    384:        s = KopString(getoa(ob,i));
                    385:        s = oxEvalEnvVar(s);
                    386:        type = oxsIsURI(s);
                    387:        if (type == NULL) {
                    388:          argv[i] = s;
                    389:        }else{
                    390:          /* Case when argv[i] is like "stringInOut:abc.poly" */
                    391:          v = oxsURIgetVarName(s);
                    392:          ext = oxsURIgetExtension(s);
                    393:          if (strcmp(type,"stringIn") == 0) {
                    394:                argv[i] = oxsVarToFile(v,ext,argv[0],usetmp);
                    395:                AfterDeleteFile[AfterD++] = argv[i];
                    396:          }else if (strcmp(type,"stringInOut") == 0) {
                    397:                argv[i] = oxsVarToFile(v,ext,argv[0],usetmp);
                    398:                AfterDeleteFile[AfterD++] = argv[i];
                    399:                AfterReadFile[AfterPt] = argv[i];
                    400:                AfterSetVar[AfterPt] = v;
                    401:                AfterPt++;
                    402:                if (AfterPt >= MAXFILES) {
                    403:                  AfterPt=0;
                    404:                  errorKan1("%s\n","oxsBuildArgv(), Too may files to open.");
                    405:                }
                    406:          }else if (strcmp(type,"stringOut") == 0) {
                    407:                argv[i] = generateTMPfileName2(v,ext,usetmp,win);
                    408:                AfterDeleteFile[AfterD++] = argv[i];
                    409:                AfterReadFile[AfterPt] = argv[i];
                    410:                AfterSetVar[AfterPt] = v;
                    411:                AfterPt++;
                    412:                if (AfterPt >= MAXFILES) {
                    413:                  AfterPt=0;
                    414:                  errorKan1("%s\n","oxsBuildArgv(), Too may files to open.");
                    415:                }
                    416:          }else {
                    417:                errorKan1("%s\n","This URI type has not yet been implemented.");
                    418:          }
                    419:          if (AfterD >= MAXFILES) {
                    420:                  AfterD=0;
                    421:                  errorKan1("%s\n","oxsBuildArgv(), Too may files to open.");
                    422:          }
                    423:        }
                    424:   }
                    425:   return(argv);
                    426: }
                    427:
                    428:
                    429: static struct object oxsExecuteBlocked(struct object ob)
                    430: {
                    431:   int r,i,n;
                    432:   char **argv;
                    433:
                    434:   /* bug: Set stdout, stderr to result variables. */
                    435:   argv = oxsBuildArgv(ob);
                    436:   r=oxForkExecBlocked(argv);  /* bug: what happen when NoX? */
                    437:   /*
                    438:   if (1) {
                    439:        for (i=0; argv[i] != NULL; i++) {
                    440:          fprintf(stderr,"argv[%d]=%s\n",i,argv[i]);
                    441:        }
                    442:        errorKan1("%s\n","ForkExecBlocked failed.");
                    443:   }
                    444:   */
                    445:   if (AfterPt > 0) {
                    446:        for (i=0; i< AfterPt; i++) {
                    447:          oxsFileToVar(AfterSetVar[i],AfterReadFile[i]);
                    448:        }
                    449:   }
                    450:   AfterPt = 0;
                    451:
                    452:   if (AfterD > 0) {
                    453:        for (i=0; i< AfterD; i++) {
                    454:          /* oxDeleteFile(AfterDeleteFile[i]);  not implemented. */
                    455:        }
                    456:   }
                    457:   AfterD = 0;
                    458:
                    459:   return(KpoInteger(r));
                    460: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>