[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.3

1.3     ! takayama    1: /* $OpenXM: OpenXM/src/kan96xx/Kan/shell.c,v 1.2 2003/12/03 01:21:43 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;
        !           355:
        !           356:   /* bug: win variable must be properly set on windows native. */
        !           357:
        !           358:   if (ob.tag != Sarray) errorKan1("%s\n","oxsBuildArgv() requires an array as an argument.");
        !           359:   n = getoaSize(ob);
        !           360:   for (i=0; i<n; i++) {
        !           361:        if (getoa(ob,i).tag != Sdollar) errorKan1("%s\n","oxsBuildArgv() requires an array of string as an argument.");
        !           362:   }
        !           363:
        !           364:   argv = (char **) mymalloc(sizeof(char *)*(n+2));
        !           365:   argv[0] = (char *)NULL;
        !           366:   if (n == 0) return(argv);
        !           367:
        !           368:   s = KopString(getoa(ob,0));
        !           369:   s = oxEvalEnvVar(s);
        !           370:   argv[0] = oxWhich(s,(char *)getenv("PATH"));
        !           371:   argv[1] = (char *)NULL;
        !           372:   if (argv[0] == NULL) {
        !           373:        fprintf(stderr,"cmdname=%s\n",s);
        !           374:        errorKan1("%s\n","oxsBuildArgv() Command is not found.\n");
        !           375:   }
        !           376:   for (i=1; i<n; i++) {
        !           377:        argv[i] = argv[i+1] = NULL;
        !           378:        s = KopString(getoa(ob,i));
        !           379:        s = oxEvalEnvVar(s);
        !           380:        type = oxsIsURI(s);
        !           381:        if (type == NULL) {
        !           382:          argv[i] = s;
        !           383:        }else{
        !           384:          /* Case when argv[i] is like "stringInOut:abc.poly" */
        !           385:          v = oxsURIgetVarName(s);
        !           386:          ext = oxsURIgetExtension(s);
        !           387:          if (strcmp(type,"stringIn") == 0) {
        !           388:                argv[i] = oxsVarToFile(v,ext,argv[0],usetmp);
        !           389:                AfterDeleteFile[AfterD++] = argv[i];
        !           390:          }else if (strcmp(type,"stringInOut") == 0) {
        !           391:                argv[i] = oxsVarToFile(v,ext,argv[0],usetmp);
        !           392:                AfterDeleteFile[AfterD++] = argv[i];
        !           393:                AfterReadFile[AfterPt] = argv[i];
        !           394:                AfterSetVar[AfterPt] = v;
        !           395:                AfterPt++;
        !           396:                if (AfterPt >= MAXFILES) {
        !           397:                  AfterPt=0;
        !           398:                  errorKan1("%s\n","oxsBuildArgv(), Too may files to open.");
        !           399:                }
        !           400:          }else if (strcmp(type,"stringOut") == 0) {
        !           401:                argv[i] = generateTMPfileName2(v,ext,usetmp,win);
        !           402:                AfterDeleteFile[AfterD++] = argv[i];
        !           403:                AfterReadFile[AfterPt] = argv[i];
        !           404:                AfterSetVar[AfterPt] = v;
        !           405:                AfterPt++;
        !           406:                if (AfterPt >= MAXFILES) {
        !           407:                  AfterPt=0;
        !           408:                  errorKan1("%s\n","oxsBuildArgv(), Too may files to open.");
        !           409:                }
        !           410:          }else {
        !           411:                errorKan1("%s\n","This URI type has not yet been implemented.");
        !           412:          }
        !           413:          if (AfterD >= MAXFILES) {
        !           414:                  AfterD=0;
        !           415:                  errorKan1("%s\n","oxsBuildArgv(), Too may files to open.");
        !           416:          }
        !           417:        }
        !           418:   }
        !           419:   return(argv);
        !           420: }
        !           421:
        !           422:
        !           423: static struct object oxsExecuteBlocked(struct object ob)
        !           424: {
        !           425:   int r,i,n;
        !           426:   char **argv;
        !           427:
        !           428:   /* bug: Set stdout, stderr to result variables. */
        !           429:   argv = oxsBuildArgv(ob);
        !           430:   r=oxForkExecBlocked(argv);  /* bug: what happen when NoX? */
        !           431:   /*
        !           432:   if (1) {
        !           433:        for (i=0; argv[i] != NULL; i++) {
        !           434:          fprintf(stderr,"argv[%d]=%s\n",i,argv[i]);
        !           435:        }
        !           436:        errorKan1("%s\n","ForkExecBlocked failed.");
        !           437:   }
        !           438:   */
        !           439:   if (AfterPt > 0) {
        !           440:        for (i=0; i< AfterPt; i++) {
        !           441:          oxsFileToVar(AfterSetVar[i],AfterReadFile[i]);
        !           442:        }
        !           443:   }
        !           444:   AfterPt = 0;
        !           445:
        !           446:   if (AfterD > 0) {
        !           447:        for (i=0; i< AfterD; i++) {
        !           448:          /* oxDeleteFile(AfterDeleteFile[i]);  not implemented. */
        !           449:        }
        !           450:   }
        !           451:   AfterD = 0;
        !           452:
        !           453:   return(KpoInteger(r));
        !           454: }

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