1 /*
2 * $Id: shellcm.c,v 1.5 2002/07/06 08:51:42 isizaka Exp isizaka $
3 *
4 * This file is part of "Ngraph for X11".
5 *
6 * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
7 *
8 * "Ngraph for X11" is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * "Ngraph for X11" is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24 /**
25 *
26 * $Log: shellcm.c,v $
27 * Revision 1.5 2002/07/06 08:51:42 isizaka
28 * change to GPL.
29 *
30 * Revision 1.4 2001/03/23 12:15:31 isizaka
31 * for 6.3.13
32 *
33 * Revision 1.3 1999/04/15 12:15:27 isizaka
34 * for release 6.03.01
35 *
36 * Revision 1.2 1999/04/11 06:08:10 isizaka
37 * *** empty log message ***
38 *
39 * Revision 1.1 1999/03/17 13:46:09 isizaka
40 * Initial revision
41 *
42 *
43 **/
44
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <ctype.h>
49 #include <errno.h>
50 #ifndef WINDOWS
51 #include <unistd.h>
52 #else
53 #include <dir.h>
54 #endif
55 #include "ngraph.h"
56 #include "object.h"
57 #include "nstring.h"
58 #include "ioutil.h"
59 #include "mathcode.h"
60 #include "mathfn.h"
61 #include "shell.h"
62 #include "shellcm.h"
63
64 #define TRUE 1
65 #define FALSE 0
66
67 #define ERR 128
68
cmcd(struct nshell * nshell,int argc,char ** argv)69 int cmcd(struct nshell *nshell,int argc,char **argv)
70 {
71 char *home;
72
73 if (argv[1]!=NULL) {
74 if (chdir(argv[1])!=0) {
75 sherror3(argv[0],ERRNODIR,argv[1]);
76 return ERR;
77 }
78 } else {
79 if ((home=getval(nshell,"HOME"))!=NULL) {
80 if (chdir(home)!=0) {
81 sherror3(argv[0],ERRNODIR,home);
82 return ERR;
83 }
84 }
85 }
86 return 0;
87 }
88
cmecho(struct nshell * nshell,int argc,char ** argv)89 int cmecho(struct nshell *nshell,int argc,char **argv)
90 {
91 int i;
92
93 for (i=1;i<argc;i++) {
94 printfstdout("%.256s",argv[i]);
95 if (i!=(argc-1)) printfstdout(" ");
96 }
97 putstdout("");
98 return 0;
99 }
100
cmeval(struct nshell * nshell,int argc,char ** argv)101 int cmeval(struct nshell *nshell,int argc,char **argv)
102 {
103 char *s;
104 int i,rcode;
105
106 if ((s=nstrnew())==NULL) return ERR;
107 for (i=1;i<argc;i++) {
108 if ((s=nstrcat(s,argv[i]))==NULL) return ERR;
109 if ((s=nstrccat(s,' '))==NULL) return ERR;
110 }
111 rcode=cmdexecute(nshell,s);
112 memfree(s);
113 if ((rcode!=0) && (rcode!=1)) return ERR;
114 return 0;
115 }
116
cmexit(struct nshell * nshell,int argc,char ** argv)117 int cmexit(struct nshell *nshell,int argc,char **argv)
118 {
119 int a;
120 char *endptr;
121
122 if (argc>2) {
123 sherror4(argv[0],ERREXTARG);
124 return ERREXTARG;
125 } else if (argc==2) {
126 a=strtol(argv[1],&endptr,10);
127 if (endptr[0]!='\0') {
128 sherror3(argv[0],ERRNUMERIC,argv[1]);
129 return ERRNUMERIC;
130 } else {
131 nshell->quit=TRUE;
132 return a;
133 }
134 } else {
135 nshell->quit=TRUE;
136 return nshell->status;
137 }
138 }
139
cmexport(struct nshell * nshell,int argc,char ** argv)140 int cmexport(struct nshell *nshell,int argc,char **argv)
141 {
142 int i;
143 struct explist *valcur;
144
145 if (argv[1]==NULL) {
146 valcur=nshell->exproot;
147 while (valcur!=NULL) {
148 printfstdout("%.256s\n",valcur->val);
149 valcur=valcur->next;
150 }
151 return 0;
152 } else {
153 for (i=1;i<argc;i++)
154 if (addexp(nshell,argv[1])==NULL) return ERR;
155 return 0;
156 }
157 }
158
cmpwd(struct nshell * nshell,int argc,char ** argv)159 int cmpwd(struct nshell *nshell,int argc,char **argv)
160 {
161 char *s;
162
163 if ((s=ngetcwd())==NULL) return ERR;
164 putstdout(s);
165 memfree(s);
166 return 0;
167 }
168
cmset(struct nshell * nshell,int argc,char ** argv)169 int cmset(struct nshell *nshell,int argc,char **argv)
170 {
171 struct vallist *valcur;
172 struct cmdlist *cmdcur;
173 struct prmlist *prmcur;
174 char *s;
175 int i,j,ops;
176 char **argv2;
177 int argc2;
178
179 if (argc<2) {
180 valcur=nshell->valroot;
181 while (valcur!=NULL) {
182 if (!valcur->func)
183 printfstdout("%.256s=%.256s\n",valcur->name,(char *)(valcur->val));
184 valcur=valcur->next;
185 }
186 valcur=nshell->valroot;
187 while (valcur!=NULL) {
188 if (valcur->func) {
189 printfstdout("%.256s=()\n",valcur->name);
190 putstdout("{");
191 cmdcur=valcur->val;
192 while (cmdcur!=NULL) {
193 prmcur=cmdcur->prm;
194 printfstdout(" ");
195 while (prmcur!=NULL) {
196 if (prmcur->str!=NULL) printfstdout("%.256s ",prmcur->str);
197 prmcur=prmcur->next;
198 }
199 printfstdout("\n");
200 cmdcur=cmdcur->next;
201 }
202 putstdout("}");
203 }
204 valcur=valcur->next;
205 }
206 } else {
207 for (j=1;j<argc;j++) {
208 s=argv[j];
209 if ((s[0]=='-') && (s[1]=='-')) {
210 for (i=1;i<=strlen(argv[j]);i++) argv[j][i-1]=argv[j][i];
211 break;
212 } else if ((s[0]=='-') || (s[0]=='+')) {
213 if ((s[1]=='\0') || (strchr("efvx",s[1])==NULL)) {
214 sherror3(argv[0],ERRILOPS,s);
215 return ERRILOPS;
216 }
217 } else break;
218 }
219 if (j!=argc) {
220 argv2=NULL;
221 if ((s=memalloc(strlen((nshell->argv)[0])+1))==NULL) return ERR;
222 strcpy(s,(nshell->argv)[0]);
223 if (arg_add(&argv2,s)==NULL) {
224 memfree(s);
225 arg_del(argv2);
226 return ERR;
227 }
228 for (;j<argc;j++) {
229 if ((s=memalloc(strlen(argv[j])+1))==NULL) return ERR;
230 strcpy(s,argv[j]);
231 if (arg_add(&argv2,s)==NULL) {
232 memfree(s);
233 arg_del(argv2);
234 return ERR;
235 }
236 }
237 argc2=getargc(argv2);
238 arg_del(nshell->argv);
239 nshell->argv=argv2;
240 nshell->argc=argc2;
241 }
242 for (j=1;j<argc;j++) {
243 s=argv[j];
244 if (s[0]=='-') ops=TRUE;
245 else if (s[0]=='+') ops=FALSE;
246 else break;
247 switch (s[1]) {
248 case 'e':
249 nshell->optione=ops;
250 break;
251 case 'f':
252 nshell->optionf=ops;
253 break;
254 case 'v':
255 nshell->optionv=ops;
256 break;
257 case 'x':
258 nshell->optionx=ops;
259 break;
260 }
261 }
262 }
263 return 0;
264 }
265
cmshift(struct nshell * nshell,int argc,char ** argv)266 int cmshift(struct nshell *nshell,int argc,char **argv)
267 {
268 int i,a;
269 char *arg,*endptr;
270
271 if (argc>2) {
272 sherror4(argv[0],ERREXTARG);
273 return ERREXTARG;
274 } else if (argc==2) {
275 arg=argv[1];
276 a=strtol(arg,&endptr,10);
277 if (endptr[0]!='\0') {
278 sherror3(argv[0],ERRNUMERIC,arg);
279 return ERRNUMERIC;
280 }
281 } else a=1;
282
283 if (a<0) a=0;
284 if ((a+1)>=nshell->argc) a=nshell->argc-1;
285 for (i=a+1;i<nshell->argc;i++) {
286 memfree(nshell->argv[i-a]);
287 nshell->argv[i-a]=nshell->argv[i];
288 nshell->argv[i]=NULL;
289 }
290 nshell->argc-=a;
291 return 0;
292 }
293
cmtype(struct nshell * nshell,int argc,char ** argv)294 int cmtype(struct nshell *nshell,int argc,char **argv)
295 {
296 struct prmlist *prm2;
297 struct cmdlist *cmdcur;
298 int i,j;
299 char *cmdname;
300
301 for (j=1;j<argc;j++) {
302 for (i=1;i<CPCMDNUM;i++)
303 if (strcmp0(cpcmdtable[i],argv[j])==0) break;
304 if (i!=CPCMDNUM) {
305 printfstdout("%.256s is a shell keyword.\n",argv[j]);
306 } else if ((cmdcur=getfunc(nshell,argv[j]))!=NULL) {
307 printfstdout("%.256s is a function.\n",argv[j]);
308 printfstdout("%.256s=()\n",argv[j]);
309 putstdout("{");
310 while (cmdcur!=NULL) {
311 prm2=cmdcur->prm;
312 printfstdout(" ");
313 while (prm2!=NULL) {
314 if (prm2->str!=NULL) printfstdout("%.256s ",prm2->str);
315 prm2=prm2->next;
316 }
317 printfstdout("\n");
318 cmdcur=cmdcur->next;
319 }
320 putstdout("}");
321 } else if ((strcmp0(".",argv[j])==0)
322 || (strcmp0("break",argv[j])==0)
323 || (strcmp0("continue",argv[j])==0)
324 || (strcmp0("return",argv[j])==0)) {
325 printfstdout("%.256s is a shell builtin.\n",argv[j]);
326 } else {
327 for (i=0;i<CMDNUM;i++)
328 if (strcmp0(argv[j],cmdtable[i].name)==0) break;
329 if (i!=CMDNUM) {
330 printfstdout("%.256s is a shell builtin.\n",argv[j]);
331 } else {
332 cmdname=nsearchpath(getval(nshell,"PATH"),argv[j],FALSE);
333 if (cmdname==NULL) {
334 sherror3(argv[0],ERRCFOUND,argv[j]);
335 } else {
336 printfstdout("%.256s is %.256s.\n",argv[j],cmdname);
337 }
338 memfree(cmdname);
339 }
340 }
341 }
342 return 0;
343 }
344
cmunset(struct nshell * nshell,int argc,char ** argv)345 int cmunset(struct nshell *nshell,int argc,char **argv)
346 {
347 int i;
348
349 for (i=1;i<argc;i++) {
350 if ((strcmp0(argv[i],"PATH")!=0) && (strcmp0(argv[i],"PS1")!=0)
351 && (strcmp0(argv[i],"PS2")!=0) && (strcmp0(argv[i],"IFS")!=0)) {
352 if (!delval(nshell,argv[i])) return ERR;
353 } else {
354 sherror3(argv[0],ERRUNSET,argv[i]);
355 return ERR;
356 }
357 }
358 return 0;
359 }
360
objdisp(struct objlist * root,struct objlist * parent,int * tab)361 void objdisp(struct objlist *root,struct objlist *parent,int *tab)
362 {
363 int i;
364 struct objlist *objcur;
365
366 (*tab)++;
367 objcur=root;
368 while (objcur!=NULL) {
369 if (objcur->parent==parent) {
370 for (i=1;i<*tab;i++) printfstdout("\t");
371 printfstdout("%.256s\n",objcur->name);
372 objdisp(objcur,objcur,tab);
373 }
374 objcur=objcur->next;
375 }
376 (*tab)--;
377 }
378
dispfield(struct objlist * obj,char * name)379 void dispfield(struct objlist *obj,char *name)
380 {
381 int j,ftype;
382 char perm[4],type[10];
383 char *alist;
384 char **enumlist;
385
386 ftype=chkobjfieldtype(obj,name);
387 switch (ftype) {
388 case NVOID: strcpy(type,"void"); break;
389 case NBOOL: strcpy(type,"bool"); break;
390 case NCHAR: strcpy(type,"char"); break;
391 case NINT: strcpy(type,"int"); break;
392 case NDOUBLE: strcpy(type,"double"); break;
393 case NSTR: strcpy(type,"char*"); break;
394 case NPOINTER: strcpy(type,"void*"); break;
395 case NIARRAY: strcpy(type,"int[]"); break;
396 case NDARRAY: strcpy(type,"double[]"); break;
397 case NSARRAY: strcpy(type,"*char[]"); break;
398 case NENUM: strcpy(type,"enum("); break;
399 case NOBJ: strcpy(type,"obj"); break;
400 case NLABEL: strcpy(type,"label"); break;
401 case NVFUNC: strcpy(type,"void("); break;
402 case NBFUNC: strcpy(type,"bool("); break;
403 case NCFUNC: strcpy(type,"char("); break;
404 case NIFUNC: strcpy(type,"int("); break;
405 case NDFUNC: strcpy(type,"double("); break;
406 case NSFUNC: strcpy(type,"*char("); break;
407 case NIAFUNC: strcpy(type,"int[]("); break;
408 case NDAFUNC: strcpy(type,"double[]("); break;
409 case NSAFUNC: strcpy(type,"*char[]("); break;
410 default: strcpy(type,"unknown"); break;
411 }
412 if (chkobjperm(obj,name) & NREAD) perm[0]='r';
413 else perm[0]='-';
414 if (chkobjperm(obj,name) & NWRITE) perm[1]='w';
415 else perm[1]='-';
416 if (chkobjperm(obj,name) & NEXEC) perm[2]='x';
417 else perm[2]='-';
418 perm[3]='\0';
419 printfstdout("%3s %15.256s %.256s",
420 (char *)perm,(char *)name,(char *)type);
421 if (ftype>=NVFUNC) {
422 if ((alist=chkobjarglist(obj,name))!=NULL) {
423 if (alist[0]=='\0') printfstdout(" void");
424 else
425 for (j=0;alist[j]!='\0';j++) {
426 switch (alist[j]) {
427 case 'b': printfstdout(" bool"); break;
428 case 'c': printfstdout(" char"); break;
429 case 'i': printfstdout(" int"); break;
430 case 'd': printfstdout(" double"); break;
431 case 's': printfstdout(" char *"); break;
432 case 'p': printfstdout(" void *"); break;
433 case 'o': printfstdout(" obj"); break;
434 }
435 if (alist[j+1]=='a') {
436 printfstdout("[]");
437 j++;
438 }
439 }
440 }
441 printfstdout(" )");
442 } else if (ftype==NENUM) {
443 if ((enumlist=(char **)chkobjarglist(obj,name))!=NULL) {
444 for (j=0;enumlist[j]!=NULL;j++) printfstdout(" %s",enumlist[j]);
445 printfstdout(" )");
446 }
447 }
448 printfstdout("\n");
449 }
450
cmobject(struct nshell * nshell,int argc,char ** argv)451 int cmobject(struct nshell *nshell,int argc,char **argv)
452 {
453 struct objlist *obj;
454 int i,j,tab;
455 char *name;
456
457 if (argc<2) {
458 tab=0;
459 objdisp(chkobjroot(),NULL,&tab);
460 return 0;
461 } else {
462 if ((obj=getobject(argv[1]))==NULL) return ERR;
463 }
464 if (argc==2) {
465 printfstdout("object: %.256s\n",chkobjectname(obj));
466 if (chkobjectalias(obj)!=NULL)
467 printfstdout("alias: %.256s\n",chkobjectalias(obj));
468 else
469 printfstdout("alias:\n");
470 printfstdout("version: %.256s\n",chkobjver(obj));
471 if (chkobjparent(obj)!=NULL)
472 printfstdout("parent: %.256s\n",chkobjectname(chkobjparent(obj)));
473 else
474 printfstdout("parent: (null)\n");
475 printfstdout("object id: %d\n",chkobjectid(obj));
476 printfstdout("number of fields: %d\n",chkobjfieldnum(obj));
477 printfstdout("size of instance: %d\n",chkobjsize(obj));
478 printfstdout("current instance: %d\n",chkobjcurinst(obj));
479 printfstdout("last instance id: %d\n",chkobjlastinst(obj));
480 for (i=0;i<chkobjfieldnum(obj);i++) {
481 name=chkobjfieldname(obj,i);
482 dispfield(obj,name);
483 }
484 }
485 for (i=2;i<argc;i++) {
486 if (argv[i][0]=='-') {
487 if (strcmp0(argv[i]+1,"name")==0) printfstdout("%.256s\n",chkobjectname(obj));
488 else if (strcmp0(argv[i]+1,"version")==0) printfstdout("%.256s\n",chkobjver(obj));
489 else if (strcmp0(argv[i]+1,"parent")==0) {
490 if (chkobjparent(obj)!=NULL)
491 printfstdout("%.256s\n",chkobjectname(chkobjparent(obj)));
492 else
493 printfstdout("(null)\n");
494 } else if (strcmp0(argv[i]+1,"id")==0) printfstdout("%d\n",chkobjectid(obj));
495 else if (strcmp0(argv[i]+1,"filed")==0) printfstdout("%d\n",chkobjfieldnum(obj));
496 else if (strcmp0(argv[i]+1,"size")==0) printfstdout("%d\n",chkobjsize(obj));
497 else if (strcmp0(argv[i]+1,"current")==0) printfstdout("%d\n",chkobjcurinst(obj));
498 else if (strcmp0(argv[i]+1,"last")==0) printfstdout("%d\n",chkobjlastinst(obj));
499 else if (strcmp0(argv[i]+1,"instance")==0) printfstdout("%d\n",chkobjlastinst(obj)+1);
500 else if (strcmp0(argv[i]+1,"instances")==0) {
501 for (j=0;j<=chkobjlastinst(obj);j++) {
502 printfstdout("%d",j);
503 if (j!=chkobjlastinst(obj)) printfstdout(" ");
504 else printfstdout("\n");
505 }
506 } else {
507 sherror3(argv[0],ERROPTION,argv[i]);
508 return ERROPTION;
509 }
510 } else break;
511 }
512 for (;i<argc;i++) {
513 if (getobjfield(obj,argv[i])==-1) return ERR;
514 dispfield(obj,argv[i]);
515 }
516 return 0;
517 }
518
dispparent(struct objlist * parent,int noinst)519 void dispparent(struct objlist *parent,int noinst)
520 {
521 struct objlist *ocur;
522
523 ocur=chkobjroot();
524 while (ocur!=NULL) {
525 if (chkobjparent(ocur)==parent) {
526 if ((chkobjlastinst(ocur)!=-1) || (!noinst))
527 putstdout(chkobjectname(ocur));
528 dispparent(ocur,noinst);
529 }
530 ocur=ocur->next;
531 }
532 }
533
cmderive(struct nshell * nshell,int argc,char ** argv)534 int cmderive(struct nshell *nshell,int argc,char **argv)
535 {
536 struct objlist *obj;
537 int i,noinst;
538
539 noinst=FALSE;
540 for (i=1;i<argc;i++) {
541 if (argv[i][0]=='-') {
542 if (strcmp0(argv[i]+1,"instance")==0) noinst=TRUE;
543 else {
544 sherror3(argv[0],ERROPTION,argv[i]);
545 return ERROPTION;
546 }
547 } else break;
548 }
549 if (i==argc) {
550 if ((obj=getobject("object"))==NULL) return ERR;
551 if ((chkobjlastinst(obj)!=-1) || (!noinst))
552 putstdout(chkobjectname(obj));
553 dispparent(obj,noinst);
554 } else {
555 for (;i<argc;i++) {
556 if ((obj=getobject(argv[i]))==NULL) return ERR;
557 if ((chkobjlastinst(obj)!=-1) || (!noinst))
558 putstdout(chkobjectname(obj));
559 dispparent(obj,noinst);
560 }
561 }
562 return 0;
563 }
564
cmnew(struct nshell * nshell,int argc,char ** argv)565 int cmnew(struct nshell *nshell,int argc,char **argv)
566 {
567 struct objlist *obj;
568 struct narray iarray;
569 int i,anum,id;
570
571 if (argc<2) {
572 sherror4(argv[0],ERROBJARG);
573 return ERROBJARG;
574 }
575 arrayinit(&iarray,sizeof(int));
576 if (getobjilist(argv[1],&obj,&iarray,FALSE,NULL)) return ERR;
577 anum=arraynum(&iarray);
578 arraydel(&iarray);
579 if (anum!=0) {
580 sherror3(argv[0],ERRNEWINST,argv[1]);
581 arraydel(&iarray);
582 return ERRNEWINST;
583 }
584 if ((id=newobj(obj))==-1) return ERR;
585 for (i=2;i<argc;i++) {
586 if (sputfield(obj,id,argv[i])!=0) {
587 delobj(obj,id);
588 return ERR;
589 }
590 }
591 return 0;
592 }
593
cmdel(struct nshell * nshell,int argc,char ** argv)594 int cmdel(struct nshell*nshell,int argc,char **argv)
595 {
596 struct objlist *obj;
597 struct narray iarray;
598 int i,j,id,anum,*adata;
599
600 if (argc<2) {
601 sherror4(argv[0],ERROBJARG);
602 return ERROBJARG;
603 } else if (argc>2) {
604 sherror4(argv[0],ERRMANYARG);
605 return ERRMANYARG;
606 }
607 arrayinit(&iarray,sizeof(int));
608 if (getobjilist(argv[1],&obj,&iarray,TRUE,NULL)) return ERR;
609 anum=arraynum(&iarray);
610 if (anum==0) {
611 sherror4(argv[0],ERRNONEINST);
612 arraydel(&iarray);
613 return ERRNONEINST;
614 }
615 adata=arraydata(&iarray);
616 for (i=0;i<anum;i++)
617 for (j=1;j<anum;j++)
618 if (adata[j-1]<adata[j]) {
619 id=adata[j-1];
620 adata[j-1]=adata[j];
621 adata[j]=id;
622 }
623 j=0;
624 for (i=1;i<anum;i++)
625 if (adata[i]!=adata[j]) {
626 j++;
627 adata[j]=adata[i];
628 }
629 for (i=0;i<=j;i++)
630 if (delobj(obj,adata[i])==-1) {
631 arraydel(&iarray);
632 return ERR;
633 }
634 arraydel(&iarray);
635 return 0;
636 }
637
cmexist(struct nshell * nshell,int argc,char ** argv)638 int cmexist(struct nshell*nshell,int argc,char **argv)
639 {
640 struct objlist *obj;
641 struct narray iarray;
642 int anum;
643
644 if (argc<2) {
645 sherror4(argv[0],ERROBJARG);
646 return ERROBJARG;
647 } else if (argc>2) {
648 sherror4(argv[0],ERRMANYARG);
649 return ERRMANYARG;
650 }
651 arrayinit(&iarray,sizeof(int));
652 if (chkobjilist(argv[1],&obj,&iarray,TRUE,NULL)) anum=0;
653 else {
654 anum=arraynum(&iarray);
655 arraydel(&iarray);
656 }
657 printfstdout("%d\n",anum);
658 if (anum==0) return ERRNONEINST;
659 return 0;
660 }
661
cmget(struct nshell * nshell,int argc,char ** argv)662 int cmget(struct nshell*nshell,int argc,char **argv)
663 {
664 struct objlist *obj;
665 struct narray iarray;
666 char *field,*valstr;
667 int i,j,k,l,id,anum,len,*adata;
668 int nowrite,nofield,noid,quote,perm,multi;
669
670 if (argc<2) {
671 sherror4(argv[0],ERROBJARG);
672 return ERROBJARG;
673 }
674 arrayinit(&iarray,sizeof(int));
675 if (getobjilist(argv[1],&obj,&iarray,TRUE,NULL)) return ERR;
676 anum=arraynum(&iarray);
677 adata=arraydata(&iarray);
678 if (anum==0) {
679 sherror4(argv[0],ERRNONEINST);
680 arraydel(&iarray);
681 return ERRNONEINST;
682 }
683 nowrite=FALSE;
684 nofield=FALSE;
685 noid=FALSE;
686 quote=FALSE;
687 for (j=2;j<argc;j++) {
688 if (argv[j][0]=='-') {
689 if (strcmp0(argv[j]+1,"write")==0) nowrite=TRUE;
690 else if (strcmp0(argv[j]+1,"field")==0) nofield=TRUE;
691 else if (strcmp0(argv[j]+1,"id")==0) noid=TRUE;
692 else if (strcmp0(argv[j]+1,"quote")==0) quote=TRUE;
693 else {
694 sherror3(argv[0],ERROPTION,argv[j]);
695 arraydel(&iarray);
696 return ERROPTION;
697 }
698 } else break;
699 }
700 if (anum==1) multi=FALSE;
701 else multi=TRUE;
702 for (l=0;l<anum;l++) {
703 id=adata[l];
704 if (j==argc) {
705 for (i=0;i<chkobjfieldnum(obj);i++) {
706 field=chkobjfieldname(obj,i);
707 perm=chkobjperm(obj,field);
708 if (((perm&NREAD)==1) && ((perm&NEXEC)==0)
709 && (!nowrite || ((perm&NWRITE)==1))) {
710 if (sgetfield(obj,id,field,&valstr,FALSE,FALSE,quote)!=0) {
711 arraydel(&iarray);
712 return ERR;
713 }
714 if (multi && !noid) printfstdout("%d: ",id);
715 if (!nofield) printfstdout("%.256s:",field);
716 putstdout(valstr);
717 memfree(valstr);
718 }
719 }
720 } else {
721 for (k=j;k<argc;k++) {
722 field=argv[k];
723 if (!nowrite || ((chkobjperm(obj,field)&NWRITE)==1)) {
724 if (sgetfield(obj,id,field,&valstr,FALSE,FALSE,quote)!=0) {
725 arraydel(&iarray);
726 return ERR;
727 }
728 if (multi && !noid) printfstdout("%d: ",id);
729 if (!nofield) {
730 field=getitok2(&field,&len,":=");
731 printfstdout("%.256s:",field);
732 memfree(field);
733 }
734 putstdout(valstr);
735 memfree(valstr);
736 }
737 }
738 }
739 }
740 arraydel(&iarray);
741 return 0;
742 }
743
cmput(struct nshell * nshell,int argc,char ** argv)744 int cmput(struct nshell*nshell,int argc,char **argv)
745 {
746 struct objlist *obj;
747 char *image;
748 int i,j,id,anum,*adata;
749 struct narray iarray;
750
751 if (argc<2) {
752 sherror4(argv[0],ERROBJARG);
753 return ERROBJARG;
754 }
755 arrayinit(&iarray,sizeof(int));
756 if (getobjilist(argv[1],&obj,&iarray,TRUE,NULL)) return ERR;
757 anum=arraynum(&iarray);
758 adata=arraydata(&iarray);
759 if (anum==0) {
760 sherror4(argv[0],ERRNONEINST);
761 arraydel(&iarray);
762 return ERRNONEINST;
763 }
764 if (argc==2) {
765 sherror4(argv[0],ERRNOFIELD);
766 arraydel(&iarray);
767 return ERRNOFIELD;
768 }
769 for (i=0;i<anum;i++) {
770 id=adata[i];
771 if ((image=saveobj(obj,id))==NULL) {
772 arraydel(&iarray);
773 return ERR;
774 }
775 for (j=2;j<argc;j++) {
776 if (sputfield(obj,id,argv[j])!=0) {
777 restoreobj(obj,id,image);
778 arraydel(&iarray);
779 return ERR;
780 }
781 }
782 memfree(image);
783 }
784 arraydel(&iarray);
785 return 0;
786 }
787
cmcpy(struct nshell * nshell,int argc,char ** argv)788 int cmcpy(struct nshell*nshell,int argc,char **argv)
789 {
790 struct objlist *obj;
791 struct narray iarray;
792 int i,j,anum,sid,did,*adata;
793 char *field;
794 int perm,type;
795
796 if (argc<2) {
797 sherror4(argv[0],ERROBJARG);
798 return ERROBJARG;
799 }
800 arrayinit(&iarray,sizeof(int));
801 if (getobjilist(argv[1],&obj,&iarray,TRUE,NULL)) return ERR;
802 anum=arraynum(&iarray);
803 adata=arraydata(&iarray);
804 if (anum<2) {
805 sherror4(argv[0],ERRTWOINST);
806 arraydel(&iarray);
807 return ERRTWOINST;
808 }
809 for (i=1;i<anum;i++) {
810 sid=adata[0];
811 did=adata[i];
812 if (argc==2) {
813 for (j=0;j<chkobjfieldnum(obj);j++) {
814 field=chkobjfieldname(obj,j);
815 perm=chkobjperm(obj,field);
816 type=chkobjfieldtype(obj,field);
817 if (((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC)) {
818 if (copyobj(obj,field,did,sid)==-1) {
819 arraydel(&iarray);
820 return ERR;
821 }
822 }
823 }
824 } else {
825 for (j=2;j<argc;j++)
826 if (copyobj(obj,argv[j],did,sid)==-1) {
827 arraydel(&iarray);
828 return ERR;
829 }
830 }
831 }
832 arraydel(&iarray);
833 return 0;
834 }
835
cmmove(struct nshell * nshell,int argc,char ** argv)836 int cmmove(struct nshell*nshell,int argc,char **argv)
837 {
838 struct objlist *obj;
839 struct narray iarray;
840 int anum,id1,id2,*adata;
841
842 if (argc<2) {
843 sherror4(argv[0],ERROBJARG);
844 return ERROBJARG;
845 } else if (argc>2) {
846 sherror4(argv[0],ERRMANYARG);
847 return ERRMANYARG;
848 }
849 arrayinit(&iarray,sizeof(int));
850 if (getobjilist(argv[1],&obj,&iarray,TRUE,NULL)) return ERR;
851 anum=arraynum(&iarray);
852 adata=arraydata(&iarray);
853 if (anum!=2) {
854 sherror4(argv[0],ERRTWOINST);
855 arraydel(&iarray);
856 return ERRTWOINST;
857 }
858 id1=adata[0];
859 id2=adata[1];
860 arraydel(&iarray);
861 if (strcmp0(argv[0],"move")==0) {
862 if (moveobj(obj,id2,id1)==-1) return ERR;
863 } else if (strcmp0(argv[0],"exch")==0) {
864 if (exchobj(obj,id2,id1)==-1) return ERR;
865 }
866 return 0;
867 }
868
cmmovetop(struct nshell * nshell,int argc,char ** argv)869 int cmmovetop(struct nshell*nshell,int argc,char **argv)
870 {
871 struct objlist *obj;
872 struct narray iarray;
873 int i,anum,top,rcode,*adata;
874
875 if (argc<2) {
876 sherror4(argv[0],ERROBJARG);
877 return ERROBJARG;
878 } else if (argc>2) {
879 sherror4(argv[0],ERRMANYARG);
880 return ERRMANYARG;
881 }
882 arrayinit(&iarray,sizeof(int));
883 if (getobjilist(argv[1],&obj,&iarray,TRUE,NULL)) return ERR;
884 anum=arraynum(&iarray);
885 adata=arraydata(&iarray);
886 if (strcmp0(argv[0],"movetop")==0) top=0;
887 else if (strcmp0(argv[0],"moveup")==0) top=1;
888 else if (strcmp0(argv[0],"movedown")==0) top=2;
889 else top=3;
890 for (i=0;i<anum;i++) {
891 if (top==0) rcode=movetopobj(obj,adata[i]);
892 else if (top==1) rcode=moveupobj(obj,adata[i]);
893 else if (top==2) rcode=movedownobj(obj,adata[i]);
894 else rcode=movelastobj(obj,adata[i]);
895 if (rcode==-1) {
896 arraydel(&iarray);
897 return ERR;
898 }
899 }
900 arraydel(&iarray);
901 return 0;
902 }
903
cmexe(struct nshell * nshell,int argc,char ** argv)904 int cmexe(struct nshell*nshell,int argc,char **argv)
905 {
906 struct objlist *obj;
907 struct narray iarray;
908 int i,j,id,anum,*adata;
909
910 if (argc<2) {
911 sherror4(argv[0],ERROBJARG);
912 return ERROBJARG;
913 }
914 arrayinit(&iarray,sizeof(int));
915 if (getobjilist(argv[1],&obj,&iarray,TRUE,NULL)) return ERR;
916 anum=arraynum(&iarray);
917 adata=arraydata(&iarray);
918 if (anum==0) {
919 sherror4(argv[0],ERRNONEINST);
920 arraydel(&iarray);
921 return ERRNONEINST;
922 }
923 if (argc==2) {
924 sherror4(argv[0],ERRNOFIELD);
925 arraydel(&iarray);
926 return ERRNOFIELD;
927 }
928 for (j=0;j<anum;j++) {
929 id=adata[j];
930 for (i=2;i<argc;i++) {
931 if (sexefield(obj,id,argv[i])!=0) {
932 arraydel(&iarray);
933 return ERR;
934 }
935 }
936 }
937 arraydel(&iarray);
938 return 0;
939 }
940
cmdexpr(struct nshell * nshell,int argc,char ** argv)941 int cmdexpr(struct nshell*nshell,int argc,char **argv)
942 {
943 int rcode,ecode;
944 char *code;
945 double vd;
946 int i;
947 double memory[MEMORYNUM];
948 char memorystat[MEMORYNUM];
949 char *s;
950
951 if (argc<1) {
952 sherror4(argv[0],ERRSMLARG);
953 return ERRSMLARG;
954 }
955 if ((s=nstrnew())==NULL) return ERR;
956 for (i=1;i<argc;i++)
957 if ((s=nstrcat(s,argv[i]))==NULL) return ERR;
958 rcode=mathcode(s,&code,NULL,NULL,NULL,NULL,
959 FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE);
960 memfree(s);
961 if (rcode!=MCNOERR) {
962 if (rcode==MCSYNTAX) ecode=ERRMSYNTAX;
963 else if (rcode==MCILLEGAL) ecode=ERRMILLEGAL;
964 else if (rcode==MCNEST) ecode=ERRMNEST;
965 sherror4(argv[0],ERRVALUE);
966 return ecode;
967 }
968 for (i=0;i<MEMORYNUM;i++) {memory[i]=0;memorystat[i]=MNOERR;}
969 rcode=calculate(code,1,
970 0,MNOERR,0,MNOERR,0,MNOERR,
971 0,0,0,0,0,0,0,0,0,0,0,0,0,0,
972 NULL,NULL,
973 memory,memorystat,
974 NULL,NULL,
975 NULL,NULL,
976 NULL,NULL,NULL,
977 NULL,NULL,NULL,0,NULL,NULL,NULL,0,&vd);
978 memfree(code);
979 ecode=0;
980 if (rcode==MSERR) ecode=ERRMSYNTAX;
981 else if (rcode==MERR) ecode=ERRMFAT;
982 if (ecode!=0) {
983 sherror4(argv[0],ecode);
984 return ecode;
985 }
986 if (rcode==MNAN) {
987 putstdout("nan");
988 return ERR;
989 } else if (rcode==MUNDEF) {
990 putstdout("undifined");
991 return ERR;
992 }
993 if (argv[0][0]=='d') printfstdout("%.15e\n",vd);
994 else printfstdout("%d\n",nround(vd));
995 return 0;
996 }
997
cmread(struct nshell * nshell,int argc,char ** argv)998 int cmread(struct nshell *nshell,int argc,char **argv)
999 {
1000 int c,i,len;
1001 char *s,*po,*s2,*ifs;
1002
1003 if ((s=nstrnew())==NULL) return ERR;
1004 while (TRUE) {
1005 c=getstdin();
1006 if ((c=='\n') || (c==EOF)) break;
1007 if ((s=nstrccat(s,c))==NULL) return ERR;
1008 }
1009 if (argc==1) {
1010 addval(nshell,"REPLY",s);
1011 } else {
1012 po=s;
1013 ifs=getval(nshell,"IFS");
1014 for (i=1;i<argc;i++) {
1015 if ((s2=getitok2(&po,&len,ifs))!=NULL) {
1016 addval(nshell,argv[i],s2);
1017 memfree(s2);
1018 } else {
1019 addval(nshell,argv[i],"");
1020 }
1021 }
1022 }
1023 memfree(s);
1024 if (c==EOF) return ERR;
1025 else return 0;
1026 }
1027