1 /*
2 * $Id: object.c,v 1.7 2006/07/20 16:38:33 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: object.c,v $
27 * Revision 1.7 2006/07/20 16:38:33 isizaka
28 * 'offset' data alignment (thanks to Mr. Mook and Mr. tanaka)
29 *
30 * Revision 1.5 2002/07/06 08:51:42 isizaka
31 * change to GPL.
32 *
33 * Revision 1.4 2001/03/23 12:15:31 isizaka
34 * for 6.3.13
35 *
36 * Revision 1.3 1999/04/15 12:15:27 isizaka
37 * for release 6.03.01
38 *
39 * Revision 1.2 1999/04/11 06:08:10 isizaka
40 * *** empty log message ***
41 *
42 * Revision 1.1 1999/03/17 13:46:09 isizaka
43 * Initial revision
44 *
45 *
46 **/
47
48 #include <stdio.h>
49 #include <ctype.h>
50 #include <stdlib.h>
51 #include <stdarg.h>
52 #include <string.h>
53 #include <limits.h>
54 #include "ngraph.h"
55 #include "nstring.h"
56 #include "object.h"
57 #include "mathcode.h"
58 #include "mathfn.h"
59 #ifdef WINDOWS
60 #include <math.h>
61 #endif
62
63 #ifdef DEBUG
64 #ifdef WINDOWS
65 #include <dos.h>
66 #else
67 #include <unistd.h>
68 #endif
69 #endif
70
71 #define TRUE 1
72 #define FALSE 0
73
74 #define OBJ_MAX 100
75 #define INST_MAX 32767
76
77 struct objlist *objroot=NULL;
78
79 struct loopproc *looproot=NULL;
80 int ineventloop=FALSE;
81 struct loopproc *loopnext=NULL;
82
83 struct objlist *errobj=NULL;
84 char errormsg1[256]={'\0'};
85 char errormsg2[256]={'\0'};
86 char errormsg[256]={'\0'};
87 int errcode=0;
88 int globallock=FALSE;
89
90 int (*getstdin)(void);
91 int (*putstdout)(char *s);
92 int (*putstderr)(char *s);
93 int (*printfstdout)(char *fmt,...);
94 int (*printfstderr)(char *fmt,...);
95 int (*ninterrupt)(void);
96 int (*inputyn)(char *mes);
97 void (*ndisplaydialog)(char *str);
98 void (*ndisplaystatus)(char *str);
99
100
101 #define ERRNUM 25
102
103 char *errorlist[ERRNUM]={
104 "",
105 "no heap space.",
106 "parent object not found",
107 "duplicate field identifier",
108 "object id is too large",
109 "instance id is too large",
110 "object not found",
111 "field not found",
112 "only one instance is allowed.",
113 "unable to make an instance.",
114 "instance not found, id",
115 "instance not found, oid",
116 "named instance not found",
117 "not allowed to destruct.",
118 "permission denied",
119 "not defined current instance.",
120 "instance does not exist.",
121 "illegal object identifier",
122 "illegal instance identifier",
123 "illegal field identifile",
124 "extra object arguments",
125 "not enouph object argument",
126 "illegal type of object argument",
127 "instance exist. cannot overwrite object",
128 };
129
error(struct objlist * obj,int code)130 void error(struct objlist *obj,int code)
131 {
132 char *objname;
133 char **errtable;
134 int errnum;
135
136 globallock=TRUE;
137 errobj=obj;
138 errcode=code;
139 if (obj==NULL) objname="kernel";
140 else objname=obj->name;
141 if (code==ERRUNKNOWN)
142 printfstderr("%.64s: %.64s%.64s%.64s\n",
143 objname,errormsg1,errormsg,errormsg2);
144 else if (code<100) {
145 errtable=errorlist;
146 errnum=ERRNUM;
147 if ((errtable==NULL) || (code>=errnum))
148 printfstderr("%.64s: %.64s(%d)%.64s\n",objname,errormsg1,code,errormsg2);
149 else
150 printfstderr("%.64s: %.64s%.64s%.64s\n",
151 objname,errormsg1,errtable[code],errormsg2);
152 } else {
153 errtable=obj->errtable;
154 errnum=obj->errnum;
155 code=code-100;
156 if ((errtable==NULL) || (code>=errnum))
157 printfstderr("%.64s: %.64s(%d)%.64s\n",objname,errormsg1,code,errormsg2);
158 else
159 printfstderr("%.64s: %.64s%.64s%.64s\n",
160 objname,errormsg1,errtable[code],errormsg2);
161 }
162 errormsg1[0]='\0';
163 errormsg2[0]='\0';
164 errormsg[0]='\0';
165 globallock=FALSE;
166 }
167
error2(struct objlist * obj,int code,char * mes)168 void error2(struct objlist *obj,int code,char *mes)
169 {
170 if (mes!=NULL) {
171 sprintf(errormsg2," `%.64s'.",mes);
172 } else {
173 sprintf(errormsg2,".");
174 }
175 error(obj,code);
176 }
177
error22(struct objlist * obj,int code,char * mes1,char * mes2)178 void error22(struct objlist *obj,int code,char *mes1,char *mes2)
179 {
180 if (mes1!=NULL) {
181 sprintf(errormsg1,"%.64s: ",mes1);
182 } else {
183 errormsg1[0]='\0';
184 }
185 if (mes2!=NULL) {
186 sprintf(errormsg2," `%.64s'.",mes2);
187 } else {
188 sprintf(errormsg2,".");
189 }
190 error(obj,code);
191 }
192
error3(struct objlist * obj,int code,int num)193 void error3(struct objlist *obj,int code,int num)
194 {
195 sprintf(errormsg2," `%d'.",num);
196 error(obj,code);
197 }
198
vgetchar(void)199 int vgetchar(void)
200 {
201 return EOF;
202 }
203
vputs(char * s)204 int vputs(char *s)
205 {
206 return 0;
207 }
208
vnprintf(char * fmt,...)209 int vnprintf(char *fmt,...)
210 {
211 return 0;
212 }
213
seputs(char * s)214 int seputs(char *s)
215 {
216 return fputs(s,stderr);
217 }
218
seprintf(char * fmt,...)219 int seprintf(char *fmt,...)
220 {
221 int code;
222 va_list ap;
223
224 va_start(ap,fmt);
225 code=vfprintf(stderr,fmt,ap);
226 va_end(ap);
227 return code;
228 }
229
vinterrupt(void)230 int vinterrupt(void)
231 {
232 return FALSE;
233 }
234
vinputyn(char * mes)235 int vinputyn(char *mes)
236 {
237 return FALSE;
238 }
239
vdisplaydialog(char * str)240 void vdisplaydialog(char *str)
241 {
242 }
243
vdisplaywindow(char * str)244 void vdisplaywindow(char *str)
245 {
246 }
247
vdisplaystatus(char * str)248 void vdisplaystatus(char *str)
249 {
250 }
251
252 struct savedstdio stdiosave;
253
ignorestdio(struct savedstdio * save)254 void ignorestdio(struct savedstdio *save)
255 {
256 if (save==NULL) savestdio(&stdiosave);
257 else savestdio(save);
258 getstdin=vgetchar;
259 putstdout=vputs;
260 putstderr=vputs;
261 printfstdout=vnprintf;
262 printfstderr=vnprintf;
263 ndisplaydialog=vdisplaydialog;
264 ndisplaystatus=vdisplaystatus;
265 }
266
restorestdio(struct savedstdio * save)267 void restorestdio(struct savedstdio *save)
268 {
269 if (save==NULL) loadstdio(&stdiosave);
270 else loadstdio(save);
271 }
272
savestdio(struct savedstdio * save)273 void savestdio(struct savedstdio *save)
274 {
275 save->getstdin=getstdin;
276 save->putstdout=putstdout;
277 save->putstderr=putstderr;
278 save->printfstdout=printfstdout;
279 save->printfstderr=printfstderr;
280 save->ninterrupt=ninterrupt;
281 save->inputyn=inputyn;
282 save->ndisplaydialog=ndisplaydialog;
283 save->ndisplaystatus=ndisplaystatus;
284 }
285
loadstdio(struct savedstdio * save)286 void loadstdio(struct savedstdio *save)
287 {
288 getstdin=save->getstdin;
289 putstdout=save->putstdout;
290 putstderr=save->putstderr;
291 printfstdout=save->printfstdout;
292 printfstderr=save->printfstderr;
293 ninterrupt=save->ninterrupt;
294 inputyn=save->inputyn;
295 ndisplaydialog=save->ndisplaydialog;
296 ndisplaystatus=save->ndisplaystatus;
297 }
298
299
300 #ifdef DEBUG
301 struct plist *memallocroot=NULL;
302 int allocnum=0;
303 #endif
304
305 #ifdef HEAPCHK
306 extern int _heapchk(void);
307 #define _HEAPOK 2
308 #endif
309
memalloc(size_t size)310 void *memalloc(size_t size)
311 {
312 void *po;
313 #ifdef DEBUG
314 struct plist *plnew;
315 #endif
316
317 #ifdef HEAPCHK
318 if (_heapchk()!=_HEAPOK) exit(1);
319 #endif
320 if (size==0) po=NULL;
321 else po=malloc(size);
322 if ((po==NULL) && (size!=0)) error(NULL,ERRHEAP);
323 #ifdef DEBUG
324 if (po!=NULL) {
325 plnew=malloc(sizeof(struct plist));
326 plnew->next=memallocroot;
327 plnew->val=po;
328 memallocroot=plnew;
329 }
330 #endif
331 return po;
332 }
333
memrealloc(void * ptr,size_t size)334 void *memrealloc(void *ptr,size_t size)
335 {
336 void *po;
337 #ifdef DEBUG
338 struct plist *plcur,*plprev;
339 struct plist *plnew;
340 #endif
341
342 #ifdef HEAPCHK
343 if (_heapchk()!=_HEAPOK) exit(1);
344 #endif
345 if (size==0) po=NULL;
346 else po=realloc(ptr,size);
347 if ((po==NULL) && (size!=0)) error(NULL,ERRHEAP);
348
349 #ifdef DEBUG
350 if (po!=NULL) {
351 if (ptr!=NULL) {
352 plcur=memallocroot;
353 plprev=NULL;
354 while (plcur!=NULL) {
355 if (plcur->val==ptr) break;
356 plprev=plcur;
357 plcur=plcur->next;
358 }
359 if (plcur==NULL) {
360 printfconsole("*%p\n",ptr);
361 sleep(30);
362 exit(1);
363 }
364 if (plprev==NULL) memallocroot=plcur->next;
365 else plprev->next=plcur->next;
366 free(plcur);
367 }
368 plnew=malloc(sizeof(struct plist));
369 plnew->next=memallocroot;
370 plnew->val=po;
371 memallocroot=plnew;
372 }
373 #endif
374 return po;
375 }
376
memfree(void * ptr)377 void memfree(void *ptr)
378 {
379 #ifdef DEBUG
380 struct plist *plcur,*plprev;
381
382 if (ptr!=NULL) {
383 plcur=memallocroot;
384 plprev=NULL;
385 while (plcur!=NULL) {
386 if (plcur->val==ptr) break;
387 plprev=plcur;
388 plcur=plcur->next;
389 }
390 if (plcur==NULL) {
391 printfconsole("*%p\n",ptr);
392 sleep(30);
393 exit(1);
394 }
395 if (plprev==NULL) memallocroot=plcur->next;
396 else plprev->next=plcur->next;
397 free(plcur);
398 }
399 #endif
400 #ifdef HEAPCHK
401 if (_heapchk()!=_HEAPOK) exit(1);
402 #endif
403 if (ptr!=NULL) free(ptr);
404 }
405
406 #define ALLOCSIZE 32
407
arrayinit(struct narray * array,unsigned int base)408 void arrayinit(struct narray *array,unsigned int base)
409 {
410 if (array==NULL) return;
411 array->base=base;
412 array->num=0;
413 array->size=0;
414 array->data=NULL;
415 }
416
arraynew(unsigned int base)417 struct narray *arraynew(unsigned int base)
418 {
419 struct narray *array;
420
421 if ((array=memalloc(sizeof(struct narray)))==NULL) return NULL;
422 arrayinit(array,base);
423 return array;
424 }
425
arraydata(struct narray * array)426 void *arraydata(struct narray *array)
427 {
428 if (array==NULL) return NULL;
429 return array->data;
430 }
431
arraynum(struct narray * array)432 unsigned int arraynum(struct narray *array)
433 {
434 if (array==NULL) return 0;
435 return array->num;
436 }
437
arraybase(struct narray * array)438 unsigned int arraybase(struct narray *array)
439 {
440 if (array==NULL) return 0;
441 return array->base;
442 }
443
arraydel(struct narray * array)444 void arraydel(struct narray *array)
445 {
446 if (array==NULL) return;
447 memfree(array->data);
448 array->data=NULL;
449 array->size=0;
450 array->num=0;
451 }
452
arraydel2(struct narray * array)453 void arraydel2(struct narray *array)
454 {
455 int i;
456 char **data;
457
458 if (array==NULL) return;
459 data=array->data;
460 for (i=0;i<array->num;i++) memfree(data[i]);
461 memfree(array->data);
462 array->data=NULL;
463 array->size=0;
464 array->num=0;
465 }
466
arrayfree(struct narray * array)467 void arrayfree(struct narray *array)
468 {
469 if (array==NULL) return;
470 memfree(array->data);
471 memfree(array);
472 }
473
arrayfree2(struct narray * array)474 void arrayfree2(struct narray *array)
475 {
476 int i;
477 char **data;
478
479 if (array==NULL) return;
480 data=array->data;
481 for (i=0;i<array->num;i++) memfree(data[i]);
482 memfree(array->data);
483 memfree(array);
484 }
485
arrayadd(struct narray * array,void * val)486 struct narray *arrayadd(struct narray *array,void *val)
487 {
488 int size,base;
489 char *data;
490
491 if (array==NULL) return NULL;
492 if (array->num==array->size) {
493 size=array->size+ALLOCSIZE;
494 if ((data=memrealloc(array->data,array->base*size))==NULL) {
495 return NULL;
496 }
497 array->size=size;
498 array->data=data;
499 } else data=array->data;
500 base=array->base;
501 memcpy(data+array->num*base,val,base);
502 (array->num)++;
503 return array;
504 }
505
arrayadd2(struct narray * array,char ** val)506 struct narray *arrayadd2(struct narray *array,char **val)
507 {
508 int size;
509 char **data;
510 char *s;
511
512 if (array==NULL) return NULL;
513 if (*val!=NULL) {
514 if ((s=memalloc(strlen(*val)+1))==NULL) {
515 arraydel2(array);
516 return NULL;
517 }
518 strcpy(s,*val);
519 }
520 if (array->num==array->size) {
521 size=array->size+ALLOCSIZE;
522 if ((data=memrealloc(array->data,array->base*size))==NULL) {
523 return NULL;
524 }
525 array->size=size;
526 array->data=data;
527 } else data=array->data;
528 data[array->num]=s;
529 (array->num)++;
530 return array;
531 }
532
arrayins(struct narray * array,void * val,unsigned int idx)533 struct narray *arrayins(struct narray *array,void *val,unsigned int idx)
534 {
535 int i,size,base;
536 char *data;
537
538 if (array==NULL) return NULL;
539 if (idx>array->num) return NULL;
540 if (array->num==array->size) {
541 size=array->size+ALLOCSIZE;
542 if ((data=memrealloc(array->data,array->base*size))==NULL) {
543 return NULL;
544 }
545 array->size=size;
546 array->data=data;
547 } else data=array->data;
548 base=array->base;
549 for (i=array->num;i>idx;i--)
550 memcpy(data+i*base,data+(i-1)*base,base);
551 memcpy(data+idx*base,val,base);
552 (array->num)++;
553 return array;
554 }
555
arrayins2(struct narray * array,char ** val,unsigned int idx)556 struct narray *arrayins2(struct narray *array,char **val,unsigned int idx)
557 {
558 int i,size;
559 char **data;
560 char *s;
561
562 if (array==NULL) return NULL;
563 if (idx>array->num) return NULL;
564 if (*val!=NULL) {
565 if ((s=memalloc(strlen(*val)+1))==NULL) {
566 arraydel2(array);
567 return NULL;
568 }
569 strcpy(s,*val);
570 }
571 if (array->num==array->size) {
572 size=array->size+ALLOCSIZE;
573 if ((data=memrealloc(array->data,array->base*size))==NULL) {
574 return NULL;
575 }
576 array->size=size;
577 array->data=data;
578 } else data=array->data;
579 for (i=array->num;i>idx;i--)
580 data[i]=data[i-1];
581 data[idx]=s;
582 (array->num)++;
583 return array;
584 }
585
arrayndel(struct narray * array,unsigned int idx)586 struct narray *arrayndel(struct narray *array,unsigned int idx)
587 {
588 int i,base;
589 char *data;
590
591 if (array==NULL) return NULL;
592 if (idx>=array->num) return NULL;
593 data=array->data;
594 base=array->base;
595 for (i=idx+1;i<array->num;i++)
596 memcpy(data+(i-1)*base,data+i*base,base);
597 (array->num)--;
598 return array;
599 }
600
arrayndel2(struct narray * array,unsigned int idx)601 struct narray *arrayndel2(struct narray *array,unsigned int idx)
602 {
603 int i;
604 char **data;
605
606 if (array==NULL) return NULL;
607 if (idx>=array->num) return NULL;
608 data=(char **)array->data;
609 memfree(data[idx]);
610 for (i=idx+1;i<array->num;i++)
611 data[i-1]=data[i];
612 (array->num)--;
613 return array;
614 }
615
arrayput(struct narray * array,void * val,unsigned int idx)616 struct narray *arrayput(struct narray *array,void *val,unsigned int idx)
617 {
618 int base;
619 char *data;
620
621 if (array==NULL) return NULL;
622 if (idx>=array->num) return NULL;
623 data=array->data;
624 base=array->base;
625 memcpy(data+idx*base,val,base);
626 return array;
627 }
628
arrayput2(struct narray * array,char ** val,unsigned int idx)629 struct narray *arrayput2(struct narray *array,char **val,unsigned int idx)
630 {
631 char *s;
632 char **data;
633
634 if (array==NULL) return NULL;
635 if (idx>=array->num) return NULL;
636 if (*val!=NULL) {
637 if ((s=memalloc(strlen(*val)+1))==NULL) {
638 arraydel2(array);
639 return NULL;
640 }
641 strcpy(s,*val);
642 }
643 data=(char **)array->data;
644 memfree(data[idx]);
645 data[idx]=s;
646 return array;
647 }
648
arraynget(struct narray * array,unsigned int idx)649 void *arraynget(struct narray *array,unsigned int idx)
650 {
651 int base;
652 char *data;
653
654 if (array==NULL) return NULL;
655 if (idx>=array->num) return NULL;
656 data=array->data;
657 base=array->base;
658 return data+idx*base;
659 }
660
arraylast(struct narray * array)661 void *arraylast(struct narray *array)
662 {
663 int base;
664 char *data;
665
666 if (array==NULL) return NULL;
667 if (array->num==0) return NULL;
668 data=array->data;
669 base=array->base;
670 return data+(array->num-1)*base;
671 }
672
673 #define ARGBUFNUM 10
674
getargc(char ** arg)675 int getargc(char **arg)
676 {
677 int i;
678
679 if (arg==NULL) return 0;
680 for (i=0;arg[i]!=NULL;i++) ;
681 return i;
682 }
683
arg_add(char *** arg,void * ptr)684 char **arg_add(char ***arg,void *ptr)
685 {
686 int i,num;
687 char **arg2;
688
689 if (*arg==NULL) {
690 if ((*arg=memalloc(ARGBUFNUM*sizeof(void *)))==NULL)
691 return NULL;
692 (*arg)[0]=NULL;
693 }
694 i=getargc(*arg);
695 num=i/ARGBUFNUM;
696 if (i%ARGBUFNUM==ARGBUFNUM-1) {
697 if ((arg2=memrealloc(*arg,ARGBUFNUM*sizeof(void *)*(num+2)))==NULL)
698 return NULL;
699 *arg=arg2;
700 }
701 (*arg)[i]=ptr;
702 (*arg)[i+1]=NULL;
703 return *arg;
704 }
705
arg_add2(char *** arg,int argc,...)706 char **arg_add2(char ***arg,int argc,...)
707 {
708 va_list ap;
709 int i;
710
711 if (*arg==NULL) {
712 if ((*arg=memalloc(ARGBUFNUM*sizeof(void *)))==NULL)
713 return NULL;
714 (*arg)[0]=NULL;
715 }
716 va_start(ap,argc);
717 for (i=0;i<argc;i++)
718 if (arg_add(arg,va_arg(ap,void *))==NULL) return NULL;
719 va_end(ap);
720 return *arg;
721 }
722
arg_del(char ** arg)723 void arg_del(char **arg)
724 {
725 int i,argc;
726
727 if (arg==NULL) return;
728 argc=getargc(arg);
729 for (i=0;i<argc;i++) memfree(arg[i]);
730 memfree(arg);
731 }
732
registerevloop(char * objname,char * evname,struct objlist * obj,int idn,char * inst,void * local)733 void registerevloop(char *objname,char *evname,
734 struct objlist *obj,int idn,char *inst,
735 void *local)
736 {
737 struct loopproc *lpcur,*lpnew;
738
739 if (obj==NULL) return;
740 if ((lpnew=memalloc(sizeof(struct loopproc)))==NULL) return;
741 lpcur=looproot;
742 if (lpcur==NULL) looproot=lpnew;
743 else {
744 while (lpcur->next!=NULL) lpcur=lpcur->next;
745 lpcur->next=lpnew;
746 }
747 lpnew->next=NULL;
748 lpnew->objname=objname;
749 lpnew->evname=evname;
750 lpnew->obj=obj;
751 lpnew->idn=idn;
752 lpnew->inst=inst;
753 lpnew->local=local;
754 }
755
unregisterevloop(struct objlist * obj,int idn,char * inst)756 void unregisterevloop(struct objlist *obj,int idn,char *inst)
757 {
758 struct loopproc *lpcur,*lpdel,*lpprev;
759
760 lpcur=looproot;
761 lpprev=NULL;
762 while (lpcur!=NULL) {
763 if ((lpcur->obj==obj) && (lpcur->idn==idn) && (lpcur->inst==inst)) {
764 lpdel=lpcur;
765 if (loopnext==lpdel) loopnext=lpdel->next;
766 if (lpprev==NULL) looproot=lpcur->next;
767 else lpprev->next=lpdel->next;
768 lpcur=lpcur->next;
769 memfree(lpdel);
770 } else {
771 lpprev=lpcur;
772 lpcur=lpcur->next;
773 }
774 }
775 }
776
unregisterallevloop()777 void unregisterallevloop()
778 {
779 struct loopproc *lpcur,*lpdel;
780
781 lpcur=looproot;
782 while (lpcur!=NULL) {
783 lpdel=lpcur;
784 lpcur=lpcur->next;
785 memfree(lpdel);
786 }
787 looproot=NULL;
788 loopnext=NULL;
789 }
790
eventloop()791 void eventloop()
792 {
793 struct loopproc *lpcur;
794 char *argv[4];
795
796 if (looproot==NULL) return;
797 if (ineventloop) return;
798 ineventloop=TRUE;
799 ignorestdio(NULL);
800 lpcur=looproot;
801 while (lpcur!=NULL) {
802 argv[0]=lpcur->objname;
803 argv[1]=lpcur->evname;
804 argv[2]=lpcur->local;
805 argv[3]=NULL;
806 loopnext=lpcur->next;
807 __exeobj(lpcur->obj,lpcur->idn,lpcur->inst,3,argv);
808 lpcur=loopnext;
809 }
810 restorestdio(NULL);
811 ineventloop=FALSE;
812 }
813
chkobjroot()814 struct objlist *chkobjroot()
815 {
816 return objroot;
817 }
818
addobject(char * name,char * alias,char * parentname,char * ver,int tblnum,struct objtable * table,int errnum,char ** errtable,void * local,DoneProc doneproc)819 void *addobject(char *name,char *alias,char *parentname,char *ver,
820 int tblnum,struct objtable *table,
821 int errnum,char **errtable,void *local,DoneProc doneproc)
822 /* addobject() returns NULL on error */
823 {
824 struct objlist *objcur,*objprev,*objnew,*parent,*objdel;
825 int i,offset,id;
826
827 id=0;
828 objcur=objroot;
829 objprev=NULL;
830 while (objcur!=NULL) {
831 if (strcmp0(objcur->name,name)==0) {
832 if (objcur->lastinst!=-1) {
833 error2(NULL,ERROVERWRITE,name);
834 return NULL;
835 }
836 objdel=objcur;
837 objcur=objcur->next;
838 memfree(objdel);
839 break;
840 }
841 objprev=objcur;
842 objcur=objcur->next;
843 id++;
844 if (id==OBJ_MAX) {
845 error3(NULL,ERROBJNUM,id);
846 return NULL;
847 }
848 }
849 if (parentname==NULL) parent=NULL;
850 else if ((parent=chkobject(parentname))==NULL) {
851 error2(NULL,ERRPARENT,parentname);
852 return NULL;
853 }
854 if ((objnew=memalloc(sizeof(struct objlist)))==NULL) return NULL;
855 if (objprev==NULL) objroot=objnew;
856 else objprev->next=objnew;
857 objnew->next=objcur;
858 objnew->id=id;
859 objnew->curinst=-1;
860 objnew->lastinst=-1;
861 objnew->lastinst2=-1;
862 objnew->lastoid=INT_MAX;
863 objnew->name=name;
864 objnew->alias=alias;
865 objnew->ver=ver;
866 objnew->tblnum=tblnum;
867 objnew->table=table;
868 objnew->errnum=errnum;
869 objnew->errtable=errtable;
870 objnew->parent=parent;
871 objnew->root=NULL;
872 objnew->root2=NULL;
873 objnew->local=local;
874 objnew->doneproc=doneproc;
875 if (parent==NULL) offset=0;
876 else offset=parent->size;
877 if (offset%ALIGNSIZE !=0) offset=offset+(ALIGNSIZE-offset%ALIGNSIZE);
878 for (i=0;i<tblnum;i++) {
879 table[i].offset=offset;
880 switch (table[i].type) {
881 case NVOID:
882 case NLABEL:
883 case NVFUNC:
884 break;
885 case NBOOL: case NBFUNC:
886 case NINT: case NIFUNC:
887 case NCHAR: case NCFUNC:
888 case NENUM:
889 offset+=sizeof(int);
890 break;
891 case NDOUBLE: case NDFUNC:
892 offset+=sizeof(double);
893 break;
894 default:
895 offset+=sizeof(void *);
896 }
897 if (offset%ALIGNSIZE !=0) offset=offset+(ALIGNSIZE-offset%ALIGNSIZE);
898 if (table[i].attrib & NEXEC) table[i].attrib&=~NWRITE;
899 }
900 objnew->size=offset;
901 objnew->idp=chkobjoffset(objnew,"id");
902 objnew->oidp=chkobjoffset(objnew,"oid");
903 objnew->nextp=chkobjoffset(objnew,"next");
904 return objnew;
905 }
906
hideinstance(struct objlist * obj)907 void hideinstance(struct objlist *obj)
908 {
909 char *instcur,*instprev;
910 int nextp,idp;
911
912 if ((idp=obj->idp)==-1) return;
913 if ((nextp=obj->nextp)==-1) return;
914 if (obj->lastinst==-1) return;
915 if (obj->lastinst2==-1) {
916 obj->root2=obj->root;
917 obj->lastinst2=obj->lastinst;
918 } else {
919 instcur=obj->root;
920 while (instcur!=NULL) {
921 *(int *)(instcur+idp)+=obj->lastinst2+1;
922 instcur=*(char **)(instcur+nextp);
923 }
924 instcur=obj->root2;
925 instprev=NULL;
926 while (instcur!=NULL) {
927 instprev=instcur;
928 instcur=*(char **)(instcur+nextp);
929 }
930 *(char **)(instprev+nextp)=obj->root;
931 obj->lastinst2+=obj->lastinst+1;
932 }
933 obj->root=NULL;
934 obj->lastinst=-1;
935 }
936
recoverinstance(struct objlist * obj)937 void recoverinstance(struct objlist *obj)
938 {
939 char *instcur,*instprev;
940 int nextp,idp;
941
942 if ((idp=obj->idp)==-1) return;
943 if ((nextp=obj->nextp)==-1) return;
944 if (obj->lastinst2==-1) return;
945 if (obj->lastinst==-1) {
946 obj->root=obj->root2;
947 obj->lastinst=obj->lastinst2;
948 } else {
949 instcur=obj->root;
950 while (instcur!=NULL) {
951 *(int *)(instcur+idp)+=obj->lastinst2+1;
952 instcur=*(char **)(instcur+nextp);
953 }
954 instcur=obj->root2;
955 instprev=NULL;
956 while (instcur!=NULL) {
957 instprev=instcur;
958 instcur=*(char **)(instcur+nextp);
959 }
960 *(char **)(instprev+nextp)=obj->root;
961 obj->root=obj->root2;
962 obj->lastinst+=obj->lastinst2+1;
963 }
964 obj->root2=NULL;
965 obj->lastinst2=-1;
966 }
967
chkobject(char * name)968 struct objlist *chkobject(char *name)
969 /* chkobject() returns NULL when the named object is not found */
970 {
971 struct objlist *obj,*objcur;
972 char *s,*aliasname;
973 int len;
974
975 objcur=objroot;
976 obj=NULL;
977 while (objcur!=NULL) {
978 if (strcmp0(objcur->name,name)==0) obj=objcur;
979 if (objcur->alias!=NULL) {
980 s=objcur->alias;
981 while ((aliasname=getitok(&s,&len,":"))!=NULL) {
982 if (strncmp(aliasname,name,len)==0) obj=objcur;
983 }
984 }
985 objcur=objcur->next;
986 }
987 return obj;
988 }
989
chkobjectname(struct objlist * obj)990 char *chkobjectname(struct objlist *obj)
991 {
992 if (obj==NULL) return NULL;
993 return obj->name;
994 }
995
chkobjectalias(struct objlist * obj)996 char *chkobjectalias(struct objlist *obj)
997 {
998 if (obj==NULL) return NULL;
999 return obj->alias;
1000 }
1001
chkobjectlocal(struct objlist * obj)1002 void *chkobjectlocal(struct objlist *obj)
1003 {
1004 if (obj==NULL) return NULL;
1005 return obj->local;
1006 }
1007
chkobjectid(struct objlist * obj)1008 int chkobjectid(struct objlist *obj)
1009 {
1010 if (obj==NULL) return -1;
1011 return obj->id;
1012 }
1013
chkobjver(struct objlist * obj)1014 char *chkobjver(struct objlist *obj)
1015 {
1016 if (obj==NULL) return NULL;
1017 return obj->ver;
1018 }
1019
chkobjparent(struct objlist * obj)1020 struct objlist *chkobjparent(struct objlist *obj)
1021 {
1022 if (obj==NULL) return NULL;
1023 return obj->parent;
1024 }
1025
chkobjchild(struct objlist * parent,struct objlist * child)1026 int chkobjchild(struct objlist *parent,struct objlist *child)
1027 {
1028 struct objlist *p;
1029
1030 p=child;
1031 do {
1032 if (p==parent) return TRUE;
1033 p=chkobjparent(p);
1034 } while (p!=NULL);
1035 return FALSE;
1036 }
1037
chkobjsize(struct objlist * obj)1038 int chkobjsize(struct objlist *obj)
1039 {
1040 if (obj==NULL) return 0;
1041 return obj->size;
1042 }
1043
chkobjlastinst(struct objlist * obj)1044 int chkobjlastinst(struct objlist *obj)
1045 {
1046 if (obj==NULL) return -1;
1047 return obj->lastinst;
1048 }
1049
chkobjcurinst(struct objlist * obj)1050 int chkobjcurinst(struct objlist *obj)
1051 {
1052 if (obj==NULL) return -1;
1053 return obj->curinst;
1054 }
1055
chkobjoffset(struct objlist * obj,char * name)1056 int chkobjoffset(struct objlist *obj,char *name)
1057 /* chkobjoffset() returns -1 on error */
1058 {
1059 struct objlist *objcur;
1060 int i;
1061
1062 if (obj==NULL) return -1;
1063 objcur=obj;
1064 while (objcur!=NULL) {
1065 for (i=0;i<objcur->tblnum;i++)
1066 if (strcmp0(objcur->table[i].name,name)==0)
1067 return objcur->table[i].offset;
1068 objcur=objcur->parent;
1069 }
1070 return -1;
1071 }
1072
chkobjoffset2(struct objlist * obj,int tblpos)1073 int chkobjoffset2(struct objlist *obj,int tblpos)
1074 {
1075 return obj->table[tblpos].offset;
1076 }
1077
chkobjinstoid(struct objlist * obj,int oid)1078 char *chkobjinstoid(struct objlist *obj,int oid)
1079 /* chkobjinstoid() returns NULL when instance is not found */
1080 {
1081 int oidp,nextp;
1082 char *inst;
1083
1084 if ((oidp=obj->oidp)==-1) return NULL;
1085 inst=obj->root;
1086 if ((nextp=obj->nextp)==-1) {
1087 if (inst==NULL) return NULL;
1088 if (*(int *)(inst+oidp)==oid) return inst;
1089 else return NULL;
1090 } else {
1091 while (inst!=NULL) {
1092 if (*(int *)(inst+oidp)==oid) return inst;
1093 inst=*(char **)(inst+nextp);
1094 }
1095 }
1096 return NULL;
1097 }
1098
chkobjtblpos(struct objlist * obj,char * name,struct objlist ** robj)1099 int chkobjtblpos(struct objlist *obj,char *name,
1100 struct objlist **robj)
1101 /* chkobjtblpos() returns -1 on error */
1102 {
1103 struct objlist *objcur;
1104 int i;
1105
1106 objcur=obj;
1107 while (objcur!=NULL) {
1108 for (i=0;i<objcur->tblnum;i++)
1109 if (strcmp0(objcur->table[i].name,name)==0) {
1110 *robj=objcur;
1111 return i;
1112 }
1113 objcur=objcur->parent;
1114 }
1115 *robj=NULL;
1116 return -1;
1117 }
1118
chkobjinst(struct objlist * obj,int id)1119 char *chkobjinst(struct objlist *obj,int id)
1120 /* chkobjinst() returns NULL if instance is not found */
1121 {
1122 int i,nextp;
1123 char *instcur;
1124
1125 instcur=obj->root;
1126 i=0;
1127 if ((nextp=obj->nextp)==-1) {
1128 if ((instcur==NULL) || (id!=0)) {
1129 return NULL;
1130 }
1131 } else {
1132 while ((instcur!=NULL) && (id!=i)) {
1133 instcur=*(char **)(instcur+nextp);
1134 i++;
1135 }
1136 if (instcur==NULL) {
1137 return NULL;
1138 }
1139 }
1140 return instcur;
1141 }
1142
chkobjlast(struct objlist * obj)1143 char *chkobjlast(struct objlist *obj)
1144 /* chkobjlast() returns NULL if instance is not found */
1145 {
1146 char *instcur,*instprev;
1147 int nextp;
1148
1149 instcur=obj->root;
1150 nextp=obj->nextp;
1151 if (nextp!=-1) {
1152 instprev=NULL;
1153 while (instcur!=NULL) {
1154 instprev=instcur;
1155 instcur=*(char **)(instcur+nextp);
1156 }
1157 instcur=instprev;
1158 }
1159 return instcur;
1160 }
1161
chkobjprev(struct objlist * obj,int id,char ** inst,char ** prev)1162 char *chkobjprev(struct objlist *obj,int id,char **inst,char **prev)
1163 /* chkobjprev() returns NULL if instance is not found */
1164 {
1165 char *instcur,*instprev;
1166 int i,nextp;
1167
1168 if (inst!=NULL) *inst=NULL;
1169 if (prev!=NULL) *prev=NULL;
1170 instcur=obj->root;
1171 instprev=NULL;
1172 i=0;
1173 if ((nextp=obj->nextp)==-1) {
1174 if ((instcur==NULL) || (id!=0)) {
1175 return NULL;
1176 }
1177 } else {
1178 while ((instcur!=NULL) && (id!=i)) {
1179 instprev=instcur;
1180 instcur=*(char **)(instcur+nextp);
1181 i++;
1182 }
1183 if (instcur==NULL) {
1184 return NULL;
1185 }
1186 }
1187 if (inst!=NULL) *inst=instcur;
1188 if (prev!=NULL) *prev=instprev;
1189 return instcur;
1190 }
1191
chkobjid(struct objlist * obj,int id)1192 int chkobjid(struct objlist *obj,int id)
1193 /* chkobjid() returns -1 on error */
1194 {
1195 if ((id>obj->lastinst) || (id<0)) return -1;
1196 else return id;
1197 }
1198
chkobjoid(struct objlist * obj,int oid)1199 int chkobjoid(struct objlist *obj,int oid)
1200 /* chkobjoid() returns -1 on error */
1201 {
1202 int oidp,idp,nextp;
1203 char *inst;
1204
1205 if ((oidp=obj->oidp)==-1) return -1;
1206 if ((idp=obj->idp)==-1) return -1;
1207 inst=obj->root;
1208 if ((nextp=obj->nextp)==-1) {
1209 if (inst==NULL) return -1;
1210 if (*(int *)(inst+oidp)==oid) return *(int *)(inst+idp);
1211 else return -1;
1212 } else {
1213 while (inst!=NULL) {
1214 if (*(int *)(inst+oidp)==oid) return *(int *)(inst+idp);
1215 inst=*(char **)(inst+nextp);
1216 }
1217 }
1218 return -1;
1219 }
1220
chkobjname(struct objlist * obj,int * id,char * name)1221 int chkobjname(struct objlist *obj,int *id,char *name)
1222 /* chkobjname() returns -1 when named object is not found*/
1223 {
1224 int i,id2;
1225 char *iname;
1226 char *inst;
1227
1228 if (id==NULL) id2=0;
1229 else id2=*id;
1230 if (chkobjoffset(obj,"name")==-1) return -1;
1231 for (i=id2;i<=obj->lastinst;i++) {
1232 if ((inst=chkobjinst(obj,i))==NULL) return -1;
1233 if (_getobj(obj,"name",inst,&iname)==-1) return -1;
1234 if ((iname!=NULL) && (strcmp0(iname,name)==0)) {
1235 if (id!=NULL) *id=i+1;
1236 return i;
1237 }
1238 }
1239 if (id!=NULL) *id=obj->lastinst+1;
1240 return -1;
1241 }
1242
chkobjfieldnum(struct objlist * obj)1243 int chkobjfieldnum(struct objlist *obj)
1244 {
1245 struct objlist *objcur,*objcur2;
1246 char *name;
1247 int i,j,num;
1248
1249 num=0;
1250 objcur=obj;
1251 while (objcur!=NULL) {
1252 for (i=0;i<objcur->tblnum;i++) {
1253 name=objcur->table[i].name;
1254 objcur2=obj;
1255 while (objcur2!=objcur) {
1256 for (j=0;j<objcur2->tblnum;j++)
1257 if (strcmp0(name,objcur2->table[j].name)==0) goto match;
1258 objcur2=objcur2->parent;
1259 }
1260 match:
1261 if (objcur2==objcur) num++;
1262 }
1263 objcur=objcur->parent;
1264 }
1265 return num;
1266 }
1267
chkobjfieldname(struct objlist * obj,int num)1268 char *chkobjfieldname(struct objlist *obj,int num)
1269 {
1270 struct objlist *objcur,*objcur2,*objcur3;
1271 char *name;
1272 int i,j,tnum;
1273
1274 tnum=0;
1275 objcur=NULL;
1276 while (objcur!=obj) {
1277 objcur2=obj;
1278 while (objcur!=(objcur2->parent)) objcur2=objcur2->parent;
1279 for (i=0;i<objcur2->tblnum;i++) {
1280 name=objcur2->table[i].name;
1281 objcur3=obj;
1282 while (objcur3!=objcur2) {
1283 for (j=0;j<objcur3->tblnum;j++)
1284 if (strcmp0(name,objcur3->table[j].name)==0) goto match;
1285 objcur3=objcur3->parent;
1286 }
1287 match:
1288 if (objcur3==objcur2) {
1289 if (tnum==num) return name;
1290 tnum++;
1291 }
1292 }
1293 objcur=objcur2;
1294 }
1295 return NULL;
1296 }
1297
chkobjfield(struct objlist * obj,char * name)1298 int chkobjfield(struct objlist *obj,char *name)
1299 {
1300 struct objlist *objcur;
1301 int i;
1302
1303 objcur=obj;
1304 while (objcur!=NULL) {
1305 for (i=0;i<objcur->tblnum;i++)
1306 if (strcmp0(objcur->table[i].name,name)==0) return 0;
1307 objcur=objcur->parent;
1308 }
1309 return -1;
1310 }
1311
chkobjperm(struct objlist * obj,char * name)1312 int chkobjperm(struct objlist *obj,char *name)
1313 /* chkobjperm() returns 0 on error */
1314 {
1315 struct objlist *robj;
1316 int idn;
1317
1318 if ((idn=chkobjtblpos(obj,name,&robj))==-1) return 0;
1319 return robj->table[idn].attrib;
1320 }
1321
chkobjfieldtype(struct objlist * obj,char * name)1322 int chkobjfieldtype(struct objlist *obj,char *name)
1323 /* chkobjperm() returns VOID on error */
1324 {
1325 struct objlist *robj;
1326 int idn;
1327
1328 if ((idn=chkobjtblpos(obj,name,&robj))==-1) return NVOID;
1329 return robj->table[idn].type;
1330 }
1331
chkobjproc(struct objlist * obj,char * name)1332 void *chkobjproc(struct objlist *obj,char *name)
1333 {
1334 int namen;
1335 struct objlist *robj;
1336
1337 if ((namen=chkobjtblpos(obj,name,&robj))==-1) return NULL;
1338 return robj->table[namen].proc;
1339 }
1340
chkobjarglist(struct objlist * obj,char * name)1341 char *chkobjarglist(struct objlist *obj,char *name)
1342 {
1343 int namen,type;
1344 struct objlist *robj;
1345 char *arglist;
1346
1347 if ((namen=chkobjtblpos(obj,name,&robj))==-1) return NULL;
1348 type=chkobjfieldtype(obj,name);
1349 arglist=robj->table[namen].arglist;
1350 if ((arglist==NULL) && (type<NVFUNC)) {
1351 switch (type) {
1352 case NVOID:
1353 arglist="";
1354 break;
1355 case NBOOL:
1356 arglist="b";
1357 break;
1358 case NCHAR:
1359 arglist="c";
1360 break;
1361 case NINT:
1362 arglist="i";
1363 break;
1364 case NDOUBLE:
1365 arglist="d";
1366 break;
1367 case NSTR:
1368 arglist="s";
1369 break;
1370 case NPOINTER:
1371 arglist="p";
1372 break;
1373 case NIARRAY:
1374 arglist="ia";
1375 break;
1376 case NDARRAY:
1377 arglist="da";
1378 break;
1379 case NSARRAY:
1380 arglist="sa";
1381 break;
1382 case NOBJ:
1383 arglist="o";
1384 break;
1385 default:
1386 arglist="";
1387 break;
1388 }
1389 }
1390 return arglist;
1391 }
1392
getobject(char * name)1393 struct objlist *getobject(char *name)
1394 /* getobject() returns NULL when the named object is not found */
1395 {
1396 struct objlist *obj;
1397
1398 if ((obj=chkobject(name))==NULL) error2(NULL,ERROBJFOUND,name);
1399 return obj;
1400 }
1401
getobjver(char * name)1402 char *getobjver(char *name)
1403 /* getobjver() returns NULL when the named object is not found */
1404 {
1405 struct objlist *obj;
1406
1407 if ((obj=getobject(name))==NULL) return NULL;
1408 return obj->ver;
1409 }
1410
getobjcurinst(struct objlist * obj)1411 int getobjcurinst(struct objlist *obj)
1412 {
1413 if (obj->curinst==-1) {
1414 error(obj,ERROBJCINST);
1415 return -1;
1416 }
1417 return obj->curinst;
1418 }
1419
getobjlastinst(struct objlist * obj)1420 int getobjlastinst(struct objlist *obj)
1421 {
1422 if (obj->lastinst==-1) {
1423 error(obj,ERRNOINST);
1424 return -1;
1425 }
1426 return obj->lastinst;
1427 }
1428
getobjoffset(struct objlist * obj,char * name)1429 int getobjoffset(struct objlist *obj,char *name)
1430 /* getoffset() returns -1 on error */
1431 {
1432 int offset;
1433
1434 if (obj==NULL) {
1435 error(NULL,ERROBJFOUND);
1436 return -1;
1437 }
1438 if ((offset=chkobjoffset(obj,name))==-1) {
1439 if (strcmp0(name,"id")==0) error(obj,ERRNOID);
1440 else error2(obj,ERRVALFOUND,name);
1441 }
1442 return offset;
1443 }
1444
getobjtblpos(struct objlist * obj,char * name,struct objlist ** robj)1445 int getobjtblpos(struct objlist *obj,char *name,struct objlist **robj)
1446 /* getoffset() returns -1 on error */
1447 {
1448 int tblnum;
1449
1450 if (obj==NULL) {
1451 error(NULL,ERROBJFOUND);
1452 return -1;
1453 }
1454 if ((tblnum=chkobjtblpos(obj,name,robj))==-1) {
1455 if (strcmp0(name,"id")==0) error(obj,ERRNOID);
1456 else error2(obj,ERRVALFOUND,name);
1457 }
1458 return tblnum;
1459 }
1460
getobjinst(struct objlist * obj,int id)1461 char *getobjinst(struct objlist *obj,int id)
1462 /* getobjinst() returns NULL if instance is not found */
1463 {
1464 char *instcur;
1465
1466 if (obj==NULL) {
1467 error(NULL,ERROBJFOUND);
1468 return NULL;
1469 }
1470 if ((instcur=chkobjinst(obj,id))==NULL) {
1471 error3(obj,ERRIDFOUND,id);
1472 return NULL;
1473 }
1474 return instcur;
1475 }
1476
getobjprev(struct objlist * obj,int id,char ** inst,char ** prev)1477 char *getobjprev(struct objlist *obj,int id,char **inst,char **prev)
1478 /* getobjprev() returns NULL if instance is not found */
1479 {
1480 if (obj==NULL) {
1481 error(NULL,ERROBJFOUND);
1482 return NULL;
1483 }
1484 if (chkobjprev(obj,id,inst,prev)==NULL) {
1485 error3(obj,ERRIDFOUND,id);
1486 return NULL;
1487 }
1488 return *inst;
1489 }
1490
getobjinstoid(struct objlist * obj,int oid)1491 char *getobjinstoid(struct objlist *obj,int oid)
1492 {
1493 char *inst;
1494
1495 if (obj==NULL) {
1496 error(NULL,ERROBJFOUND);
1497 return NULL;
1498 }
1499 if ((inst=chkobjinstoid(obj,oid))==NULL) {
1500 error3(obj,ERROIDFOUND,oid);
1501 return NULL;
1502 }
1503 return inst;
1504 }
1505
getobjname(struct objlist * obj,int * id,char * name)1506 int getobjname(struct objlist *obj,int *id,char *name)
1507 /* getobjname() returns -1 when named instance is not found */
1508 {
1509 int i,id2;
1510 char *iname;
1511 char *inst;
1512
1513 if (id==NULL) id2=0;
1514 else id2=*id;
1515 if (getobjoffset(obj,"name")==-1) return -1;
1516 for (i=id2;i<=obj->lastinst;i++) {
1517 if ((inst=getobjinst(obj,i))==NULL) return -1;
1518 if (_getobj(obj,"name",inst,&iname)==-1) return -1;
1519 if ((iname!=NULL) && (strcmp0(iname,name)==0)) {
1520 if (id!=NULL) *id=i+1;
1521 return i;
1522 }
1523 }
1524 if (id!=NULL) *id=obj->lastinst+1;
1525 error2(obj,ERRNMFOUND,name);
1526 return -1;
1527 }
1528
getobjid(struct objlist * obj,int id)1529 int getobjid(struct objlist *obj,int id)
1530 /* getobjid() returns -1 on error */
1531 {
1532 if ((id>obj->lastinst) || (id<0)) {
1533 error3(obj,ERRIDFOUND,id);
1534 return -1;
1535 } else return id;
1536 }
1537
getobjoid(struct objlist * obj,int oid)1538 int getobjoid(struct objlist *obj,int oid)
1539 /* getobjoid() returns -1 on error */
1540 {
1541 int id;
1542
1543 if ((id=chkobjoid(obj,oid))==-1) {
1544 error3(obj,ERROIDFOUND,oid);
1545 return -1;
1546 } else return id;
1547 }
1548
getobjfield(struct objlist * obj,char * name)1549 int getobjfield(struct objlist *obj,char *name)
1550 {
1551 if (chkobjfield(obj,name)==-1) {
1552 error2(obj,ERRVALFOUND,name);
1553 return -1;
1554 } else return 0;
1555 }
1556
getobjproc(struct objlist * obj,char * vname,void * val)1557 int getobjproc(struct objlist *obj,char *vname,void *val)
1558 {
1559 struct objlist *robj;
1560 int idn;
1561 Proc proc;
1562
1563 if ((idn=getobjtblpos(obj,vname,&robj))==-1) return -1;
1564 proc=robj->table[idn].proc;
1565 *(Proc *)val=proc;
1566 return 0;
1567 }
1568
_newobj(struct objlist * obj)1569 int _newobj(struct objlist *obj)
1570 /* _newobj() returns id or -1 on error */
1571 {
1572 char *instcur,*instnew,*inst;
1573 int i,offset,nextp,id,idp,oidp;
1574 struct objlist *objcur;
1575
1576 if ((idp=obj->idp)==-1) {
1577 error(obj,ERRNOID);
1578 return -1;
1579 }
1580 id=obj->lastinst+1;
1581 if ((id+obj->lastinst2+1)==INST_MAX) {
1582 error3(obj,ERRINSTNUM,INST_MAX);
1583 return -1;
1584 }
1585 nextp=obj->nextp;
1586 if ((instcur=chkobjlast(obj))!=NULL) {
1587 if (nextp==-1) {
1588 error(obj,ERRNONEXT);
1589 return -1;
1590 }
1591 }
1592 instnew=memalloc(obj->size);
1593 if (instnew==NULL) return -1;
1594 objcur=obj;
1595 while (objcur!=NULL) {
1596 for (i=0;i<objcur->tblnum;i++) {
1597 offset=objcur->table[i].offset;
1598 switch (objcur->table[i].type) {
1599 case NVOID:
1600 case NLABEL:
1601 case NVFUNC:
1602 break;
1603 case NBOOL:
1604 case NCHAR:
1605 case NINT:
1606 case NENUM:
1607 case NBFUNC:
1608 case NCFUNC:
1609 case NIFUNC:
1610 *(int *)(instnew+offset)=0;
1611 break;
1612 case NDOUBLE:
1613 case NDFUNC:
1614 *(double *)(instnew+offset)=0.0;
1615 break;
1616 default:
1617 *(char **)(instnew+offset)=NULL;
1618 break;
1619 }
1620 }
1621 objcur=objcur->parent;
1622 }
1623 *(int *)(instnew+idp)=id;
1624 if ((oidp=obj->oidp)!=-1) {
1625 if (obj->lastoid==INT_MAX) obj->lastoid=0;
1626 else obj->lastoid++;
1627 if (nextp!=-1) {
1628 do {
1629 inst=obj->root;
1630 while (inst!=NULL) {
1631 if (*(int *)(inst+oidp)==obj->lastoid) {
1632 if (obj->lastoid==INT_MAX) obj->lastoid=0;
1633 else obj->lastoid++;
1634 break;
1635 }
1636 inst=*(char **)(inst+nextp);
1637 }
1638 if (inst==NULL) {
1639 inst=obj->root2;
1640 while (inst!=NULL) {
1641 if (*(int *)(inst+oidp)==obj->lastoid) {
1642 if (obj->lastoid==INT_MAX) obj->lastoid=0;
1643 else obj->lastoid++;
1644 break;
1645 }
1646 inst=*(char **)(inst+nextp);
1647 }
1648 }
1649 } while (inst!=NULL);
1650 }
1651 *(int *)(instnew+oidp)=obj->lastoid;
1652 }
1653
1654 if (instcur==NULL) obj->root=instnew;
1655 else *(char **)(instcur+nextp)=instnew;
1656 if (nextp!=-1) *(char **)(instnew+nextp)=NULL;
1657 obj->lastinst=id;
1658 return id;
1659 }
1660
newobj(struct objlist * obj)1661 int newobj(struct objlist *obj)
1662 /* newobj() returns id or -1 on error */
1663 {
1664 struct objlist *robj;
1665 char *instcur,*instnew,*inst;
1666 int i,offset,nextp,id,idp,oidp,rcode,initn,initp;
1667 int argc;
1668 char **argv;
1669 struct objlist *objcur;
1670
1671 if ((idp=obj->idp)==-1) {
1672 error(obj,ERRNOID);
1673 return -1;
1674 }
1675 if ((initn=getobjtblpos(obj,"init",&robj))==-1) return -1;
1676 initp=chkobjoffset2(robj,initn);
1677 if ((robj->table[initn].attrib & NEXEC)==0) {
1678 error2(obj,ERRPERMISSION,"init");
1679 return -1;
1680 }
1681 id=obj->lastinst+1;
1682 if ((id+obj->lastinst2+1)==INST_MAX) {
1683 error3(obj,ERRINSTNUM,INST_MAX);
1684 return -1;
1685 }
1686 nextp=obj->nextp;
1687 if ((instcur=chkobjinst(obj,obj->lastinst))!=NULL) {
1688 if (nextp==-1) {
1689 error(obj,ERRNONEXT);
1690 return -1;
1691 }
1692 }
1693 instnew=memalloc(obj->size);
1694 if (instnew==NULL) return -1;
1695 objcur=obj;
1696 while (objcur!=NULL) {
1697 for (i=0;i<objcur->tblnum;i++) {
1698 offset=objcur->table[i].offset;
1699 switch (objcur->table[i].type) {
1700 case NVOID:
1701 case NLABEL:
1702 case NVFUNC:
1703 break;
1704 case NBOOL:
1705 case NCHAR:
1706 case NINT:
1707 case NENUM:
1708 case NBFUNC:
1709 case NCFUNC:
1710 case NIFUNC:
1711 *(int *)(instnew+offset)=0;
1712 break;
1713 case NDOUBLE:
1714 case NDFUNC:
1715 *(double *)(instnew+offset)=0.0;
1716 break;
1717 default:
1718 *(char **)(instnew+offset)=NULL;
1719 break;
1720 }
1721 }
1722 objcur=objcur->parent;
1723 }
1724 *(int *)(instnew+idp)=id;
1725 if ((oidp=obj->oidp)!=-1) {
1726 if (obj->lastoid==INT_MAX) obj->lastoid=0;
1727 else obj->lastoid++;
1728 if (nextp!=-1) {
1729 do {
1730 inst=obj->root;
1731 while (inst!=NULL) {
1732 if (*(int *)(inst+oidp)==obj->lastoid) {
1733 if (obj->lastoid==INT_MAX) obj->lastoid=0;
1734 else obj->lastoid++;
1735 break;
1736 }
1737 inst=*(char **)(inst+nextp);
1738 }
1739 if (inst==NULL) {
1740 inst=obj->root2;
1741 while (inst!=NULL) {
1742 if (*(int *)(inst+oidp)==obj->lastoid) {
1743 if (obj->lastoid==INT_MAX) obj->lastoid=0;
1744 else obj->lastoid++;
1745 break;
1746 }
1747 inst=*(char **)(inst+nextp);
1748 }
1749 }
1750 } while (inst!=NULL);
1751 }
1752 *(int *)(instnew+oidp)=obj->lastoid;
1753 }
1754 if (robj->table[initn].proc!=NULL) {
1755 argv=NULL;
1756 if (arg_add2(&argv,2,obj->name,"init")==NULL) {
1757 memfree(argv);
1758 return -1;
1759 }
1760 argc=getargc(argv);
1761 rcode=robj->table[initn].proc(robj,instnew,instnew+initp,argc,argv);
1762 memfree(argv);
1763 if (rcode!=0) {
1764 memfree(instnew);
1765 return -1;
1766 }
1767 }
1768 if (instcur==NULL) obj->root=instnew;
1769 else *(char **)(instcur+nextp)=instnew;
1770 if (nextp!=-1) *(char **)(instnew+nextp)=NULL;
1771 obj->lastinst=id;
1772 obj->curinst=id;
1773 return id;
1774 }
1775
_delobj(struct objlist * obj,int delid)1776 int _delobj(struct objlist *obj,int delid)
1777 /* delobj() returns id or -1 on error */
1778 {
1779 char *instcur,*instprev,*inst;
1780 int nextp,idp;
1781
1782 if ((idp=obj->idp)==-1) {
1783 error(obj,ERRNOID);
1784 return -1;
1785 }
1786 if (getobjprev(obj,delid,&instcur,&instprev)==NULL) return -1;
1787 if ((nextp=obj->nextp)==-1) obj->root=NULL;
1788 else {
1789 if (instprev==NULL) obj->root=*(char **)(instcur+nextp);
1790 else *(char **)(instprev+nextp)=*(char **)(instcur+nextp);
1791 inst=*(char **)(instcur+nextp);
1792 while (inst!=NULL) {
1793 (*(int *)(inst+idp))--;
1794 inst=*(char **)(inst+nextp);
1795 }
1796 }
1797 memfree(instcur);
1798 obj->lastinst--;
1799 return 0;
1800 }
1801
delobj(struct objlist * obj,int delid)1802 int delobj(struct objlist *obj,int delid)
1803 /* delobj() returns id or -1 on error */
1804 {
1805 struct objlist *robj,*objcur;
1806 char *instcur,*instprev,*inst;
1807 int i,nextp,idp,donen,donep,rcode,offset;
1808 int argc;
1809 char **argv;
1810 struct narray *array;
1811
1812 if ((idp=obj->idp)==-1) {
1813 error(obj,ERRNOID);
1814 return -1;
1815 }
1816 if ((donen=chkobjtblpos(obj,"done",&robj))==-1) {
1817 error(obj,ERRDESTRUCT);
1818 return -1;
1819 }
1820 donep=chkobjoffset2(robj,donen);
1821 if ((robj->table[donen].attrib & NEXEC)==0) {
1822 error2(obj,ERRPERMISSION,"done");
1823 return -1;
1824 }
1825 if (getobjprev(obj,delid,&instcur,&instprev)==NULL) return -1;
1826 if (robj->table[donen].proc!=NULL) {
1827 argv=NULL;
1828 if (arg_add2(&argv,2,obj->name,"done")==NULL) {
1829 memfree(argv);
1830 return -1;
1831 }
1832 argc=getargc(argv);
1833 rcode=robj->table[donen].proc(robj,instcur,instcur+donep,argc,argv);
1834 memfree(argv);
1835 if (rcode!=0) return -1;
1836 }
1837 if ((nextp=obj->nextp)==-1) obj->root=NULL;
1838 else {
1839 if (instprev==NULL) obj->root=*(char **)(instcur+nextp);
1840 else *(char **)(instprev+nextp)=*(char **)(instcur+nextp);
1841 inst=*(char **)(instcur+nextp);
1842 while (inst!=NULL) {
1843 (*(int *)(inst+idp))--;
1844 inst=*(char **)(inst+nextp);
1845 }
1846 *(char **)(instcur+nextp)=NULL;
1847 }
1848 objcur=obj;
1849 while (objcur!=NULL) {
1850 for (i=0;i<objcur->tblnum;i++) {
1851 offset=objcur->table[i].offset;
1852 switch (objcur->table[i].type) {
1853 case NPOINTER:
1854 case NSTR:
1855 case NOBJ:
1856 case NSFUNC:
1857 memfree(*(char **)(instcur+offset));
1858 break;
1859 case NIARRAY: case NIAFUNC:
1860 case NDARRAY: case NDAFUNC:
1861 array=*(struct narray **)(instcur+offset);
1862 arrayfree(array);
1863 break;
1864 case NSARRAY: case NSAFUNC:
1865 array=*(struct narray **)(instcur+offset);
1866 arrayfree2(array);
1867 break;
1868 default:
1869 break;
1870 }
1871 }
1872 objcur=objcur->parent;
1873 }
1874 memfree(instcur);
1875 obj->lastinst--;
1876 obj->curinst=-1;
1877 return 0;
1878 }
1879
delchildobj(struct objlist * parent)1880 void delchildobj(struct objlist *parent)
1881 {
1882 struct objlist *ocur;
1883 int i,instnum;
1884
1885 ocur=chkobjroot();
1886 while (ocur!=NULL) {
1887 if (chkobjparent(ocur)==parent) {
1888 if ((instnum=chkobjlastinst(ocur))!=-1)
1889 for (i=instnum;i>=0;i--) delobj(ocur,i);
1890 delchildobj(ocur);
1891 }
1892 ocur=ocur->next;
1893 }
1894 }
1895
_putobj(struct objlist * obj,char * vname,char * inst,void * val)1896 int _putobj(struct objlist *obj,char *vname,char *inst,void *val)
1897 {
1898 struct objlist *robj;
1899 int idp,idn;
1900
1901 if ((idn=getobjtblpos(obj,vname,&robj))==-1) return -1;
1902 idp=chkobjoffset2(robj,idn);
1903 switch (robj->table[idn].type) {
1904 case NVOID:
1905 case NLABEL:
1906 case NVFUNC:
1907 break;
1908 case NBOOL: case NBFUNC:
1909 case NINT: case NIFUNC:
1910 case NCHAR: case NCFUNC:
1911 case NENUM:
1912 *(int *)(inst+idp)=*(int *)val;
1913 break;
1914 case NDOUBLE: case NDFUNC:
1915 *(double *)(inst+idp)=*(double *)val;
1916 break;
1917 default:
1918 *(char **)(inst+idp)=(char *)val;
1919 break;
1920 }
1921 return 0;
1922 }
1923
putobj(struct objlist * obj,char * vname,int id,void * val)1924 int putobj(struct objlist *obj,char *vname,int id,void *val)
1925 /* putobj() returns id or -1 on error */
1926 {
1927 struct objlist *robj;
1928 struct narray *array;
1929 char *instcur;
1930 int idp,idn,rcode,argc;
1931 char **argv;
1932
1933 if ((idn=getobjtblpos(obj,vname,&robj))==-1) return -1;
1934 idp=chkobjoffset2(robj,idn);
1935 if ((instcur=getobjinst(obj,id))==NULL) return -1;
1936 if ((robj->table[idn].attrib & NWRITE)==0) {
1937 error2(obj,ERRPERMISSION,vname);
1938 return -1;
1939 }
1940 if ((robj->table[idn].type<NVFUNC) && (robj->table[idn].proc!=NULL)) {
1941 argv=NULL;
1942 if (arg_add2(&argv,3,obj->name,vname,val)==NULL) {
1943 memfree(argv);
1944 return -1;
1945 }
1946 argc=getargc(argv);
1947 rcode=robj->table[idn].proc(robj,instcur,instcur+idp,argc,argv);
1948 val=argv[2];
1949 memfree(argv);
1950 if (rcode!=0) return -1;
1951 }
1952 switch (robj->table[idn].type) {
1953 case NSTR:
1954 case NPOINTER:
1955 case NOBJ:
1956 case NSFUNC:
1957 memfree(*(char **)(instcur+idp));
1958 break;
1959 case NIARRAY: case NIAFUNC:
1960 case NDARRAY: case NDAFUNC:
1961 array=*(struct narray **)(instcur+idp);
1962 arrayfree(array);
1963 break;
1964 case NSARRAY: case NSAFUNC:
1965 array=*(struct narray **)(instcur+idp);
1966 arrayfree2(array);
1967 break;
1968 default:
1969 break;
1970 }
1971 switch (robj->table[idn].type) {
1972 case NVOID:
1973 case NLABEL:
1974 case NVFUNC:
1975 break;
1976 case NBOOL:
1977 case NINT:
1978 case NCHAR:
1979 case NENUM:
1980 *(int *)(instcur+idp)=*(int *)val;
1981 break;
1982 case NDOUBLE:
1983 *(double *)(instcur+idp)=*(double *)val;
1984 break;
1985 default:
1986 *(char **)(instcur+idp)=(char *)val;
1987 break;
1988 }
1989 obj->curinst=id;
1990 return id;
1991 }
1992
_getobj(struct objlist * obj,char * vname,char * inst,void * val)1993 int _getobj(struct objlist *obj,char *vname,char *inst,void *val)
1994 {
1995 struct objlist *robj;
1996 int idp,idn;
1997
1998 if ((idn=getobjtblpos(obj,vname,&robj))==-1) return -1;
1999 idp=chkobjoffset2(robj,idn);
2000 switch (robj->table[idn].type) {
2001 case NVOID: case NLABEL: case NVFUNC:
2002 break;
2003 case NBOOL: case NBFUNC:
2004 case NINT: case NIFUNC:
2005 case NCHAR: case NCFUNC:
2006 case NENUM:
2007 *(int *)val=*(int *)(inst+idp);
2008 break;
2009 case NDOUBLE: case NDFUNC:
2010 *(double *)val=*(double *)(inst+idp);
2011 break;
2012 default:
2013 *(char **)val=*(char **)(inst+idp);
2014 break;
2015 }
2016 return 0;
2017 }
2018
getobj(struct objlist * obj,char * vname,int id,int argc,char ** argv,void * val)2019 int getobj(struct objlist *obj,char *vname,int id,
2020 int argc,char **argv,void *val)
2021 /* getobj() returns id or -1 on error */
2022 {
2023 struct objlist *robj;
2024 char *instcur;
2025 int i,idp,idn;
2026 int argc2,rcode;
2027 char **argv2;
2028
2029 if ((idn=getobjtblpos(obj,vname,&robj))==-1) return -1;
2030 idp=chkobjoffset2(robj,idn);
2031 if ((instcur=getobjinst(obj,id))==NULL) return -1;
2032 if (((robj->table[idn].attrib & NREAD)==0)
2033 || ( (robj->table[idn].type>=NVFUNC)
2034 && ((robj->table[idn].attrib & NEXEC)==0))) {
2035 error2(obj,ERRPERMISSION,vname);
2036 return -1;
2037 }
2038 if ((robj->table[idn].type>=NVFUNC) && (robj->table[idn].proc!=NULL)) {
2039 argv2=NULL;
2040 if (arg_add2(&argv2,2,obj->name,vname)==NULL) {
2041 memfree(argv2);
2042 return -1;
2043 }
2044 for (i=0;i<argc;i++)
2045 if (arg_add(&argv2,((char **)argv)[i])==NULL) {
2046 memfree(argv2);
2047 return -1;
2048 }
2049 argc2=getargc(argv2);
2050 rcode=robj->table[idn].proc(robj,instcur,instcur+idp,argc2,argv2);
2051 memfree(argv2);
2052 if (rcode!=0) return -1;
2053 }
2054 switch (robj->table[idn].type) {
2055 case NVOID: case NLABEL: case NVFUNC:
2056 break;
2057 case NBOOL: case NBFUNC:
2058 case NINT: case NIFUNC:
2059 case NCHAR: case NCFUNC:
2060 case NENUM:
2061 *(int *)val=*(int *)(instcur+idp);
2062 break;
2063 case NDOUBLE: case NDFUNC:
2064 *(double *)val=*(double *)(instcur+idp);
2065 break;
2066 default:
2067 *(char **)val=*(char **)(instcur+idp);
2068 break;
2069 }
2070 obj->curinst=id;
2071 return id;
2072 }
2073
_exeparent(struct objlist * obj,char * vname,char * inst,char * rval,int argc,char ** argv)2074 int _exeparent(struct objlist *obj,char *vname,char *inst,char *rval,
2075 int argc,char **argv)
2076 /* _exeparent() returns errorlevel or -1 on error */
2077 {
2078 struct objlist *parent,*robj;
2079 int idn,idp,rcode;
2080 char *rval2;
2081
2082 if ((parent=obj->parent)==NULL) return 0;
2083 if ((idn=chkobjtblpos(parent,vname,&robj))==-1) return 0;
2084 idp=chkobjoffset2(robj,idn);
2085 if (chkobjfieldtype(parent,vname)<NVFUNC) return -1;
2086 if (rval==NULL) rval2=inst+idp;
2087 else rval2=rval;
2088 if (robj->table[idn].proc!=NULL) {
2089 rcode=robj->table[idn].proc(robj,inst,rval2,argc,argv);
2090 } else rcode=0;
2091 return rcode;
2092 }
2093
__exeobj(struct objlist * obj,int idn,char * inst,int argc,char ** argv)2094 int __exeobj(struct objlist *obj,int idn,char *inst,int argc,char **argv)
2095 /* __exeobj() returns errorlevel or -1 on error */
2096 {
2097 int rcode,idp;
2098
2099 if (obj->table[idn].type<NVFUNC) return -1;
2100 if (obj->table[idn].proc!=NULL) {
2101 idp=chkobjoffset2(obj,idn);
2102 rcode=obj->table[idn].proc(obj,inst,inst+idp,argc,argv);
2103 } else rcode=0;
2104 return rcode;
2105 }
2106
_exeobj(struct objlist * obj,char * vname,char * inst,int argc,char ** argv)2107 int _exeobj(struct objlist *obj,char *vname,char *inst,int argc,char **argv)
2108 /* _exeobj() returns errorlevel or -1 on error */
2109 {
2110 struct objlist *robj;
2111 int i,idn,idp,rcode;
2112 int argc2;
2113 char **argv2;
2114
2115 if ((idn=getobjtblpos(obj,vname,&robj))==-1) return -1;
2116 idp=chkobjoffset2(robj,idn);
2117 if (robj->table[idn].type<NVFUNC) return -1;
2118 if (robj->table[idn].proc!=NULL) {
2119 argv2=NULL;
2120 if (arg_add2(&argv2,2,obj->name,vname)==NULL) {
2121 memfree(argv2);
2122 return -1;
2123 }
2124 for (i=0;i<argc;i++)
2125 if (arg_add(&argv2,((char **)argv)[i])==NULL) {
2126 memfree(argv2);
2127 return -1;
2128 }
2129 argc2=getargc(argv2);
2130 rcode=robj->table[idn].proc(robj,inst,inst+idp,argc2,argv2);
2131 memfree(argv2);
2132 } else rcode=0;
2133 return rcode;
2134 }
2135
exeobj(struct objlist * obj,char * vname,int id,int argc,char ** argv)2136 int exeobj(struct objlist *obj,char *vname,int id,int argc,char **argv)
2137 /* exeobj() returns errorlevel or -1 on error */
2138 {
2139 struct objlist *robj;
2140 char *instcur;
2141 int i,idn,idp,rcode;
2142 int argc2;
2143 char **argv2;
2144
2145 if ((idn=getobjtblpos(obj,vname,&robj))==-1) return -1;
2146 idp=chkobjoffset2(robj,idn);
2147 if ((instcur=getobjinst(obj,id))==NULL) return -1;
2148 if ((robj->table[idn].type<NVFUNC)
2149 || ((robj->table[idn].attrib & NREAD)==0)
2150 || ( (robj->table[idn].type>=NVFUNC)
2151 && ((robj->table[idn].attrib & NEXEC)==0))) {
2152 error2(obj,ERRPERMISSION,vname);
2153 return -1;
2154 }
2155 if (robj->table[idn].proc!=NULL) {
2156 argv2=NULL;
2157 if (arg_add2(&argv2,2,obj->name,vname)==NULL) {
2158 memfree(argv2);
2159 return -1;
2160 }
2161 for (i=0;i<argc;i++)
2162 if (arg_add(&argv2,((char **)argv)[i])==NULL) {
2163 memfree(argv2);
2164 return -1;
2165 }
2166 argc2=getargc(argv2);
2167 rcode=robj->table[idn].proc(robj,instcur,instcur+idp,argc2,argv2);
2168 memfree(argv2);
2169 } else rcode=0;
2170 obj->curinst=id;
2171 return rcode;
2172 }
2173
copyobj(struct objlist * obj,char * vname,int did,int sid)2174 int copyobj(struct objlist *obj,char *vname,int did,int sid)
2175 {
2176 struct objlist *robj;
2177 int i,idn;
2178 char value[8];
2179 char *po;
2180 struct narray *array;
2181 char *s;
2182
2183 if ((idn=getobjtblpos(obj,vname,&robj))==-1) return -1;
2184 if (((robj->table[idn].attrib & NREAD)==0)
2185 || ((robj->table[idn].attrib & NWRITE)==0)
2186 || (robj->table[idn].type>=NVFUNC)) {
2187 error2(obj,ERRPERMISSION,vname);
2188 return -1;
2189 }
2190 po=value;
2191 if (getobj(obj,vname,sid,0,NULL,po)==-1) return -1;
2192 switch (robj->table[idn].type) {
2193 case NVOID:
2194 case NLABEL:
2195 case NBOOL:
2196 case NINT:
2197 case NCHAR:
2198 case NENUM:
2199 case NDOUBLE:
2200 if (putobj(obj,vname,did,po)==-1) return -1;
2201 break;
2202 case NSTR:
2203 case NOBJ:
2204 if (*(char **)po==NULL) {
2205 if (putobj(obj,vname,did,NULL)==-1) return -1;
2206 } else {
2207 if ((s=memalloc(strlen(*(char **)po)+1))==NULL) return -1;
2208 strcpy(s,*(char **)po);
2209 if (putobj(obj,vname,did,s)==-1) return -1;
2210 }
2211 break;
2212 case NIARRAY:
2213 case NDARRAY:
2214 if (*(struct narray **)po==NULL) {
2215 if (putobj(obj,vname,did,NULL)==-1) return -1;
2216 } else {
2217 if ((array=arraynew(arraybase(*(struct narray **)po)))==NULL) return -1;
2218 for (i=0;i<arraynum(*(struct narray **)po);i++) {
2219 if (arrayadd(array,arraynget(*(struct narray **)po,i))==NULL) {
2220 arrayfree(array);
2221 return -1;
2222 }
2223 }
2224 if (putobj(obj,vname,did,array)==-1) {
2225 arrayfree(array);
2226 return -1;
2227 }
2228 }
2229 break;
2230 case NSARRAY:
2231 if (*(struct narray **)po==NULL) {
2232 if (putobj(obj,vname,did,NULL)==-1) return -1;
2233 } else {
2234 if ((array=arraynew(arraybase(*(struct narray **)po)))==NULL) return -1;
2235 for (i=0;i<arraynum(*(struct narray **)po);i++) {
2236 if (arrayadd2(array,arraynget(*(struct narray **)po,i))==NULL) {
2237 arrayfree2(array);
2238 return -1;
2239 }
2240 }
2241 if (putobj(obj,vname,did,array)==-1) {
2242 arrayfree2(array);
2243 return -1;
2244 }
2245 }
2246 break;
2247 default:
2248 if (putobj(obj,vname,did,*(char **)po)) return -1;
2249 break;
2250 }
2251 return did;
2252 }
2253
_copyobj(struct objlist * obj,int did,int sid)2254 int _copyobj(struct objlist *obj,int did,int sid)
2255 /* _copyobj() returns id or -1 on error */
2256 {
2257 char *dinstcur;
2258 char *sinstcur,*instnext;
2259 int idp,id,nextp;
2260
2261 if ((idp=obj->idp)==-1) {
2262 error(obj,ERRNOID);
2263 return -1;
2264 }
2265 if ((sinstcur=getobjinst(obj,sid))==NULL) return -1;
2266 if (did==sid) return did;
2267 if ((dinstcur=chkobjinst(obj,did))==NULL) {
2268 if ((did=newobj(obj))==-1) return -1;
2269 if ((dinstcur=getobjinst(obj,did))==NULL) return -1;
2270 }
2271 id=*(int *)(dinstcur+idp);
2272 if ((nextp=obj->nextp)==-1) {
2273 error2(obj,ERRVALFOUND,"next");
2274 return -1;
2275 }
2276 instnext=*(char **)(dinstcur+nextp);
2277 memcpy(dinstcur,sinstcur,obj->size);
2278 *(int *)(dinstcur+idp)=id;
2279 *(char **)(dinstcur+nextp)=instnext;
2280 obj->curinst=did;
2281 return did;
2282 }
2283
moveobj(struct objlist * obj,int did,int sid)2284 int moveobj(struct objlist *obj,int did,int sid)
2285 /* moveobj() returns id or -1 on error */
2286 {
2287 char *dinstcur;
2288 int id,idp;
2289
2290 if ((idp=obj->idp)==-1) {
2291 error(obj,ERRNOID);
2292 return -1;
2293 }
2294 if (getobjid(obj,sid)==-1) return -1;
2295 if (did==sid) return did;
2296 if ((dinstcur=chkobjinst(obj,did))==NULL) {
2297 if ((id=_newobj(obj))==-1) return -1;
2298 if (_copyobj(obj,id,sid)==-1) {
2299 _delobj(obj,id);
2300 return -1;
2301 }
2302 if (_delobj(obj,sid)==-1) {
2303 _delobj(obj,id);
2304 return -1;
2305 }
2306 } else {
2307 exchobj(obj,did,sid);
2308 if (delobj(obj,sid)==-1) {
2309 exchobj(obj,did,sid);
2310 return -1;
2311 }
2312 }
2313 obj->curinst=*(int *)(dinstcur+idp);
2314 return *(int *)(dinstcur+idp);
2315 }
2316
moveupobj(struct objlist * obj,int id)2317 int moveupobj(struct objlist *obj,int id)
2318 /* moveupobj() returns id or -1 on error */
2319 {
2320 char *instcur,*instprev,*instcur2,*instprev2;
2321 char *inst;
2322 int idp,nextp;
2323
2324 if ((idp=obj->idp)==-1) {
2325 error(obj,ERRNOID);
2326 return -1;
2327 }
2328 if (getobjprev(obj,id,&instcur,&instprev)==NULL) return -1;
2329 if (id==0) return id;
2330 if ((nextp=obj->nextp)==-1) {
2331 error2(obj,ERRVALFOUND,"next");
2332 return -1;
2333 }
2334 if (getobjprev(obj,id-1,&instcur2,&instprev2)==NULL) return -1;
2335 inst=*(char **)(instcur+nextp);
2336 if (instprev2==NULL) obj->root=instcur;
2337 else *(char **)(instprev2+nextp)=instcur;
2338 *(char **)(instcur+nextp)=instprev;
2339 if (instprev==NULL) obj->root=inst;
2340 else *(char **)(instprev+nextp)=inst;
2341 (*(int *)(instcur+idp))--;
2342 (*(int *)(instprev+idp))++;
2343 obj->curinst=id-1;
2344 return id-1;
2345 }
2346
movetopobj(struct objlist * obj,int id)2347 int movetopobj(struct objlist *obj,int id)
2348 /* movetopobj() returns id or -1 on error */
2349 {
2350 char *instcur,*instprev;
2351 char *rinst,*pinst,*inst;
2352 int idp,nextp;
2353
2354 if ((idp=obj->idp)==-1) {
2355 error(obj,ERRNOID);
2356 return -1;
2357 }
2358 if (getobjprev(obj,id,&instcur,&instprev)==NULL) return -1;
2359 if (id==0) return id;
2360 if ((nextp=obj->nextp)==-1) {
2361 error2(obj,ERRVALFOUND,"next");
2362 return -1;
2363 }
2364 rinst=obj->root;
2365 inst=*(char **)(instcur+nextp);
2366 pinst=*(char **)(instprev+nextp);
2367 obj->root=pinst;
2368 *(char **)(instcur+nextp)=rinst;
2369 *(char **)(instprev+nextp)=inst;
2370 *(int *)(instcur+idp)=0;
2371 instcur=rinst;
2372 while (instcur!=inst) {
2373 (*(int *)(instcur+idp))++;
2374 instcur=*(char **)(instcur+nextp);
2375 }
2376 obj->curinst=0;
2377 return 0;
2378 }
2379
movedownobj(struct objlist * obj,int id)2380 int movedownobj(struct objlist *obj,int id)
2381 /* movedownobj() returns id or -1 on error */
2382 {
2383 char *instcur,*instprev;
2384 char *ninst,*inst;
2385 int idp,nextp,lid;
2386
2387 if ((idp=obj->idp)==-1) {
2388 error(obj,ERRNOID);
2389 return -1;
2390 }
2391 if (getobjprev(obj,id,&instcur,&instprev)==NULL) return -1;
2392 lid=chkobjlastinst(obj);
2393 if (id==lid) return id;
2394 if ((nextp=obj->nextp)==-1) {
2395 error2(obj,ERRVALFOUND,"next");
2396 return -1;
2397 }
2398 inst=*(char **)(instcur+nextp);
2399 ninst=*(char **)(inst+nextp);
2400 if (instprev==NULL) obj->root=inst;
2401 else *(char **)(instprev+nextp)=inst;
2402 *(char **)(inst+nextp)=instcur;
2403 *(char **)(instcur+nextp)=ninst;
2404 (*(int *)(instcur+idp))++;
2405 (*(int *)(inst+idp))--;
2406 obj->curinst=id+1;
2407 return id+1;
2408 }
2409
movelastobj(struct objlist * obj,int id)2410 int movelastobj(struct objlist *obj,int id)
2411 /* movetopobj() returns id or -1 on error */
2412 {
2413 char *instcur,*instprev,*lastinst;
2414 char *pinst,*inst;
2415 int idp,nextp,lid;
2416
2417 if ((idp=obj->idp)==-1) {
2418 error(obj,ERRNOID);
2419 return -1;
2420 }
2421 if (getobjprev(obj,id,&instcur,&instprev)==NULL) return -1;
2422 lid=chkobjlastinst(obj);
2423 if ((lastinst=getobjinst(obj,lid))==NULL) return -1;
2424 if (id==lid) return id;
2425 if ((nextp=obj->nextp)==-1) {
2426 error2(obj,ERRVALFOUND,"next");
2427 return -1;
2428 }
2429 inst=*(char **)(instcur+nextp);
2430 if (instprev==NULL) pinst=obj->root;
2431 else pinst=*(char **)(instprev+nextp);
2432 *(char **)(lastinst+nextp)=pinst;
2433 *(char **)(instcur+nextp)=NULL;
2434 if (instprev==NULL) obj->root=inst;
2435 else *(char **)(instprev+nextp)=inst;
2436 *(int *)(instcur+idp)=lid;
2437 while (inst!=instcur) {
2438 (*(int *)(inst+idp))--;
2439 inst=*(char **)(inst+nextp);
2440 }
2441 obj->curinst=lid;
2442 return lid;
2443 }
2444
exchobj(struct objlist * obj,int id1,int id2)2445 int exchobj(struct objlist *obj,int id1,int id2)
2446 /* exchobj() returns id or -1 on error */
2447 {
2448 char *instcur1,*instprev1;
2449 char *instcur2,*instprev2;
2450 char *inst,*inst1,*inst2;
2451 int idp,id,nextp;
2452
2453 if ((idp=obj->idp)==-1) {
2454 error(obj,ERRNOID);
2455 return -1;
2456 }
2457 if ((getobjprev(obj,id1,&instcur1,&instprev1)==NULL)
2458 || (getobjprev(obj,id2,&instcur2,&instprev2)==NULL)) return -1;
2459 if (id1==id2) return id1;
2460 if ((nextp=obj->nextp)==-1) {
2461 error2(obj,ERRVALFOUND,"next");
2462 return -1;
2463 }
2464 id=*(int *)(instcur1+idp);
2465 *(int *)(instcur1+idp)=*(int *)(instcur2+idp);
2466 *(int *)(instcur2+idp)=id;
2467 if (instprev1==NULL) inst1=obj->root;
2468 else inst1=*(char **)(instprev1+nextp);
2469 if (instprev2==NULL) inst2=obj->root;
2470 else inst2=*(char **)(instprev2+nextp);
2471 if (instprev1==NULL) obj->root=inst2;
2472 else *(char **)(instprev1+nextp)=inst2;
2473 if (instprev2==NULL) obj->root=inst1;
2474 else *(char **)(instprev2+nextp)=inst1;
2475 inst=*(char **)(instcur1+nextp);
2476 *(char **)(instcur1+nextp)=*(char **)(instcur2+nextp);
2477 *(char **)(instcur2+nextp)=inst;
2478 obj->curinst=id2;
2479 return id2;
2480 }
2481
saveobj(struct objlist * obj,int id)2482 char *saveobj(struct objlist *obj,int id)
2483 {
2484 char *instcur,*instnew;
2485
2486 if ((instcur=getobjinst(obj,id))==NULL) return NULL;
2487 if ((instnew=memalloc(obj->size))==NULL) return NULL;
2488 memcpy(instnew,instcur,obj->size);
2489 return instnew;
2490 }
2491
restoreobj(struct objlist * obj,int id,char * image)2492 char *restoreobj(struct objlist *obj,int id,char *image)
2493 {
2494 char *instcur;
2495
2496 if (obj==NULL) return NULL;
2497 if ((instcur=getobjinst(obj,id))==NULL) return NULL;
2498 memcpy(instcur,image,obj->size);
2499 memfree(image);
2500 return instcur;
2501 }
2502
chkilist(struct objlist * obj,char * ilist,struct narray * iarray,int def,int * spc)2503 int chkilist(struct objlist *obj,char *ilist,struct narray *iarray,int def,int *spc)
2504 /* spc 0: not found
2505 1: specified by id
2506 2: specified by oid
2507 3: specified by name
2508 4: specified by other
2509 */
2510
2511 {
2512 int i,len,snum,dnum,num,sid,l;
2513 int oid;
2514 char *tok,*s,*iname,*endptr;
2515
2516 *spc=0;
2517 num=0;
2518 tok=NULL;
2519 if ((ilist==NULL) || (ilist[0]=='\0')) {
2520 if (def) {
2521 if ((snum=chkobjcurinst(obj))==-1) return -1;
2522 if (arrayadd(iarray,&snum)==NULL) goto errexit;
2523 num++;
2524 *spc=4;
2525 }
2526 } else {
2527 while ((s=getitok2(&ilist,&len," \t,"))!=NULL) {
2528 memfree(tok);
2529 tok=s;
2530 iname=NULL;
2531 if (s[0]=='@') {
2532 if ((snum=chkobjcurinst(obj))==-1) goto errexit;
2533 s++;
2534 *spc=4;
2535 } else if (s[0]=='!') {
2536 if ((snum=chkobjlastinst(obj))==-1) goto errexit;
2537 s++;
2538 *spc=4;
2539 } else {
2540 if (s[0]=='^') {
2541 oid=TRUE;
2542 s++;
2543 } else oid=FALSE;
2544 l=strtol(s,&endptr,10);
2545 if (s!=endptr) {
2546 if (oid) {
2547 snum=chkobjoid(obj,l);
2548 *spc=2;
2549 } else {
2550 snum=chkobjid(obj,l);
2551 *spc=1;
2552 }
2553 if (snum==-1) goto errexit;
2554 }
2555 s=endptr;
2556 }
2557 if (s==tok) {
2558 snum=0;
2559 if ((dnum=chkobjlastinst(obj))==-1) goto errexit;
2560 iname=tok;
2561 } else if (s[0]=='-') {
2562 s++;
2563 if (s[0]=='@') {
2564 if ((dnum=chkobjcurinst(obj))==-1) goto errexit;
2565 *spc=4;
2566 } else if (s[0]=='!') {
2567 if ((dnum=chkobjlastinst(obj))==-1) goto errexit;
2568 *spc=4;
2569 } else {
2570 l=strtol(s,&endptr,10);
2571 if (endptr[0]!='\0') {
2572 goto errexit;
2573 } else {
2574 dnum=getobjid(obj,l);
2575 if (dnum==-1) goto errexit;
2576 *spc=1;
2577 }
2578 }
2579 } else if (s[0]=='+') {
2580 *spc=4;
2581 s++;
2582 if (s[0]=='@') {
2583 if ((dnum=chkobjcurinst(obj))==-1) goto errexit;
2584 } else if (s[0]=='!') {
2585 if ((dnum=chkobjlastinst(obj))==-1) goto errexit;
2586 } else {
2587 l=strtol(s,&endptr,10);
2588 if (endptr[0]!='\0') {
2589 goto errexit;
2590 } else {
2591 dnum=l;
2592 }
2593 }
2594 snum+=dnum;
2595 dnum=snum;
2596 } else if (s[0]=='\0') {
2597 dnum=snum;
2598 } else {
2599 goto errexit;
2600 }
2601 if (iname==NULL) {
2602 for (i=snum;i<=dnum;i++) {
2603 if (chkobjid(obj,i)==-1) goto errexit;
2604 if (arrayadd(iarray,&i)==NULL) goto errexit;
2605 num++;
2606 }
2607 } else {
2608 *spc=3;
2609 sid=0;
2610 if (chkobjname(obj,&sid,iname)==-1) goto errexit;
2611 sid=0;
2612 while ((snum=chkobjname(obj,&sid,iname))>=0) {
2613 if (arrayadd(iarray,&snum)==NULL) goto errexit;
2614 num++;
2615 }
2616 }
2617 }
2618 }
2619 memfree(tok);
2620 return num;
2621
2622 errexit:
2623 memfree(tok);
2624 arraydel(iarray);
2625 return -1;
2626 }
2627
getilist(struct objlist * obj,char * ilist,struct narray * iarray,int def,int * spc)2628 int getilist(struct objlist *obj,char *ilist,struct narray *iarray,int def,int *spc)
2629 /* spc 0: not found
2630 1: specified by id
2631 2: specified by oid
2632 3: specified by name
2633 4: specified by other
2634 */
2635
2636 {
2637 int i,len,snum,dnum,num,sid,l;
2638 int oid;
2639 char *tok,*s,*iname,*endptr;
2640
2641 *spc=0;
2642 num=0;
2643 tok=NULL;
2644 if ((ilist==NULL) || (ilist[0]=='\0')) {
2645 if (def) {
2646 if ((snum=getobjcurinst(obj))==-1) return -1;
2647 if (arrayadd(iarray,&snum)==NULL) goto errexit;
2648 num++;
2649 *spc=4;
2650 }
2651 } else {
2652 while ((s=getitok2(&ilist,&len," \t,"))!=NULL) {
2653 memfree(tok);
2654 tok=s;
2655 iname=NULL;
2656 if (s[0]=='@') {
2657 if ((snum=getobjcurinst(obj))==-1) goto errexit;
2658 s++;
2659 *spc=4;
2660 } else if (s[0]=='!') {
2661 if ((snum=getobjlastinst(obj))==-1) goto errexit;
2662 s++;
2663 *spc=4;
2664 } else {
2665 if (s[0]=='^') {
2666 oid=TRUE;
2667 s++;
2668 } else oid=FALSE;
2669 l=strtol(s,&endptr,10);
2670 if (s!=endptr) {
2671 if (oid) {
2672 snum=getobjoid(obj,l);
2673 *spc=2;
2674 } else {
2675 snum=getobjid(obj,l);
2676 *spc=1;
2677 }
2678 if (snum==-1) goto errexit;
2679 }
2680 s=endptr;
2681 }
2682 if (s==tok) {
2683 snum=0;
2684 if ((dnum=getobjlastinst(obj))==-1) goto errexit;
2685 iname=tok;
2686 } else if (s[0]=='-') {
2687 s++;
2688 if (s[0]=='@') {
2689 if ((dnum=getobjcurinst(obj))==-1) goto errexit;
2690 *spc=4;
2691 } else if (s[0]=='!') {
2692 if ((dnum=getobjlastinst(obj))==-1) goto errexit;
2693 *spc=4;
2694 } else {
2695 l=strtol(s,&endptr,10);
2696 if (endptr[0]!='\0') {
2697 error2(obj,ERRILINST,tok);
2698 goto errexit;
2699 } else {
2700 dnum=getobjid(obj,l);
2701 if (dnum==-1) goto errexit;
2702 *spc=1;
2703 }
2704 }
2705 } else if (s[0]=='+') {
2706 *spc=4;
2707 s++;
2708 if (s[0]=='@') {
2709 if ((dnum=getobjcurinst(obj))==-1) goto errexit;
2710 } else if (s[0]=='!') {
2711 if ((dnum=getobjlastinst(obj))==-1) goto errexit;
2712 } else {
2713 l=strtol(s,&endptr,10);
2714 if (endptr[0]!='\0') {
2715 error2(obj,ERRILINST,tok);
2716 goto errexit;
2717 } else {
2718 dnum=l;
2719 }
2720 }
2721 snum+=dnum;
2722 dnum=snum;
2723 } else if (s[0]=='\0') {
2724 dnum=snum;
2725 } else {
2726 error2(obj,ERRILINST,tok);
2727 goto errexit;
2728 }
2729 if (iname==NULL) {
2730 for (i=snum;i<=dnum;i++) {
2731 if (getobjid(obj,i)==-1) goto errexit;
2732 if (arrayadd(iarray,&i)==NULL) goto errexit;
2733 num++;
2734 }
2735 } else {
2736 *spc=3;
2737 sid=0;
2738 if (getobjname(obj,&sid,iname)==-1) goto errexit;
2739 sid=0;
2740 while ((snum=chkobjname(obj,&sid,iname))>=0) {
2741 if (arrayadd(iarray,&snum)==NULL) goto errexit;
2742 num++;
2743 }
2744 }
2745 }
2746 }
2747 memfree(tok);
2748 return num;
2749
2750 errexit:
2751 memfree(tok);
2752 arraydel(iarray);
2753 return -1;
2754 }
2755
chkobjilist(char * s,struct objlist ** obj,struct narray * iarray,int def,int * spc)2756 int chkobjilist(char *s,struct objlist **obj,struct narray *iarray,int def,int *spc)
2757 {
2758 char *oname,*ilist;
2759 int len;
2760 int spc2;
2761
2762 if (s==NULL) return -1;
2763 if ((s[0]==':') || ((oname=getitok2(&s,&len,":"))==NULL)) {
2764 if (len==-1) return -1;
2765 return ERRILOBJ;
2766 }
2767 if ((*obj=chkobject(oname))==NULL) {
2768 memfree(oname);
2769 return -1;
2770 }
2771 memfree(oname);
2772 if (s[0]==':') s++;
2773 ilist=s;
2774 if (def && (chkobjlastinst(*obj)==-1)) return -1;
2775 if (chkilist(*obj,ilist,iarray,def,&spc2)==-1) return -1;
2776 if (spc!=NULL) *spc=spc2;
2777 return 0;
2778 }
2779
getobjilist(char * s,struct objlist ** obj,struct narray * iarray,int def,int * spc)2780 int getobjilist(char *s,struct objlist **obj,struct narray *iarray,int def,int *spc)
2781 {
2782 char *oname,*ilist;
2783 int len;
2784 int spc2;
2785
2786 if (s==NULL) return -1;
2787 if ((s[0]==':') || ((oname=getitok2(&s,&len,":"))==NULL)) {
2788 if (len==-1) return -1;
2789 error2(NULL,ERRILOBJ,s);
2790 return ERRILOBJ;
2791 }
2792 if ((*obj=getobject(oname))==NULL) {
2793 memfree(oname);
2794 return -1;
2795 }
2796 memfree(oname);
2797 if (s[0]==':') s++;
2798 ilist=s;
2799 if (def && (getobjlastinst(*obj)==-1)) return -1;
2800 if (getilist(*obj,ilist,iarray,def,&spc2)==-1) return -1;
2801 if (spc!=NULL) *spc=spc2;
2802 return 0;
2803 }
2804
chkobjilist2(char ** s,struct objlist ** obj,struct narray * iarray,int def)2805 int chkobjilist2(char **s,struct objlist **obj,struct narray *iarray,int def)
2806 {
2807 char *oname,*ilist;
2808 int len,num,spc;
2809
2810 if ((oname=getitok2(s,&len,":"))==NULL) {
2811 if (len==-1) return -1;
2812 return ERRILOBJ;
2813 }
2814 if ((*obj=chkobject(oname))==NULL) {
2815 memfree(oname);
2816 return -1;
2817 }
2818 memfree(oname);
2819 if (def && (chkobjlastinst(*obj)==-1)) return -1;
2820 if ((*s)[0]=='\0') {
2821 return ERRILOBJ;
2822 } else if ((*s)[0]==':') (*s)++;
2823 if ((*s)[0]==':') ilist=NULL;
2824 else {
2825 if ((ilist=getitok2(s,&len,":"))==NULL) {
2826 if (len==-1) return -1;
2827 return ERRILOBJ;
2828 }
2829 }
2830 num=chkilist(*obj,ilist,iarray,def,&spc);
2831 memfree(ilist);
2832 if (num==-1) return -1;
2833 if (((*s)[0]!='\0') && ((*s)[0]==':')) (*s)++;
2834 return 0;
2835 }
2836
getobjilist2(char ** s,struct objlist ** obj,struct narray * iarray,int def)2837 int getobjilist2(char **s,struct objlist **obj,struct narray *iarray,int def)
2838 {
2839 char *oname,*ilist;
2840 int len,num,spc;
2841
2842 if ((oname=getitok2(s,&len,":"))==NULL) {
2843 if (len==-1) return -1;
2844 error2(NULL,ERRILOBJ,*s);
2845 return ERRILOBJ;
2846 }
2847 if ((*obj=getobject(oname))==NULL) {
2848 memfree(oname);
2849 return -1;
2850 }
2851 memfree(oname);
2852 if (def && (getobjlastinst(*obj)==-1)) return -1;
2853 if ((*s)[0]=='\0') {
2854 error2(NULL,ERRILOBJ,*s);
2855 return ERRILOBJ;
2856 } else if ((*s)[0]==':') (*s)++;
2857 if ((*s)[0]==':') ilist=NULL;
2858 else {
2859 if ((ilist=getitok2(s,&len,":"))==NULL) {
2860 if (len==-1) return -1;
2861 error2(NULL,ERRILOBJ,*s);
2862 return ERRILOBJ;
2863 }
2864 }
2865 num=getilist(*obj,ilist,iarray,def,&spc);
2866 memfree(ilist);
2867 if (num==-1) return -1;
2868 if (((*s)[0]!='\0') && ((*s)[0]==':')) (*s)++;
2869 return 0;
2870 }
2871
mkobjlist(struct objlist * obj,char * objname,int id,char * field,int oid)2872 char *mkobjlist(struct objlist *obj,char *objname,int id,char *field,int oid)
2873 {
2874 char ids[11];
2875 char *s;
2876 int len,flen;
2877
2878 if (objname==NULL) objname=chkobjectname(obj);
2879 if (oid) sprintf(ids,"^%d",id);
2880 else sprintf(ids,"%d",id);
2881 if (field!=NULL) flen=strlen(field);
2882 else flen=0;
2883 if ((s=memalloc(strlen(objname)+strlen(ids)+flen+3))==NULL)
2884 return NULL;
2885 strcpy(s,objname);
2886 len=strlen(s);
2887 s[len]=':';
2888 strcpy(s+len+1,ids);
2889 if (field!=NULL) {
2890 len=strlen(s);
2891 s[len]=':';
2892 strcpy(s+len+1,field);
2893 }
2894 return s;
2895 }
2896
getobjlist(char * list,int * id,char ** field,int * oid)2897 struct objlist *getobjlist(char *list,int *id,char **field,int *oid)
2898 {
2899 char *objname;
2900 char *ids,*ids2;
2901 int len;
2902 struct objlist *obj;
2903 char *endptr;
2904
2905 objname=getitok2(&list,&len,":");
2906 ids=getitok2(&list,&len,":");
2907 *field=getitok(&list,&len,":");
2908 if ((objname==NULL) || (ids==NULL) || (*field==NULL)) {
2909 memfree(objname);
2910 memfree(ids);
2911 *field=NULL;
2912 return NULL;
2913 }
2914 obj=chkobject(objname);
2915 memfree(objname);
2916 if (ids[0]=='^') {
2917 if (oid!=NULL) *oid=TRUE;
2918 ids2=ids+1;
2919 } else {
2920 if (oid!=NULL) *oid=FALSE;
2921 ids2=ids;
2922 }
2923 *id=strtol(ids2,&endptr,0);
2924 if ((ids2[0]=='\0') || (endptr[0]!='\0') || (chkobjoffset(obj,*field)==-1)) {
2925 memfree(ids);
2926 *field=NULL;
2927 return NULL;
2928 }
2929 memfree(ids);
2930 return obj;
2931 }
2932
chgobjlist(char * olist)2933 char *chgobjlist(char *olist)
2934 {
2935 char *list,*objname,*newlist;
2936 char *ids,*ids2;
2937 int id,len;
2938 struct objlist *obj;
2939 char *endptr;
2940 char *inst;
2941
2942 list=olist;
2943 objname=getitok2(&list,&len,":");
2944 ids=getitok2(&list,&len,":");
2945 if ((objname==NULL) || (ids==NULL)) {
2946 memfree(objname);
2947 memfree(ids);
2948 return NULL;
2949 }
2950 if (ids[0]!='^') {
2951 memfree(objname);
2952 memfree(ids);
2953 if ((newlist=memalloc(strlen(olist)+1))==NULL) return NULL;
2954 strcpy(newlist,olist);
2955 return newlist;
2956 }
2957 ids2=ids+1;
2958 id=strtol(ids2,&endptr,0);
2959 if ((ids2[0]=='\0') || (endptr[0]!='\0')) {
2960 memfree(objname);
2961 memfree(ids);
2962 return NULL;
2963 }
2964 memfree(ids);
2965 obj=chkobject(objname);
2966 if ((inst=chkobjinstoid(obj,id))==NULL) {
2967 memfree(objname);
2968 return NULL;
2969 }
2970 _getobj(obj,"id",inst,&id);
2971 newlist=mkobjlist(obj,objname,id,NULL,FALSE);
2972 memfree(objname);
2973 return newlist;
2974 }
2975
getvaluestr(struct objlist * obj,char * field,void * val,int cr,int quote)2976 char *getvaluestr(struct objlist *obj,char *field,void *val,int cr,int quote)
2977 {
2978 struct narray *array;
2979 void *po;
2980 char *bval,*s,*arglist;
2981 int i,k,j;
2982 int type,len;
2983
2984 arglist=chkobjarglist(obj,field);
2985 type=chkobjfieldtype(obj,field);
2986 len=0;
2987 po=val;
2988 switch (type) {
2989 case NBOOL: case NBFUNC:
2990 len+=5;
2991 break;
2992 case NCHAR: case NCFUNC:
2993 len+=1;
2994 break;
2995 case NINT: case NIFUNC:
2996 len+=11;
2997 break;
2998 case NDOUBLE: case NDFUNC:
2999 len+=23;
3000 break;
3001 case NSTR: case NSFUNC: case NOBJ:
3002 if (*(char **)po==NULL) break;
3003 else {
3004 bval=*(char **)po;
3005 if (quote) len++;
3006 for (i=0;bval[i]!='\0';i++) {
3007 if ((bval[i]=='\'') && quote) len+=3;
3008 len++;
3009 }
3010 if (quote) len++;
3011 }
3012 break;
3013 case NIARRAY: case NIAFUNC:
3014 array=*(struct narray **)po;
3015 if (array==NULL) break;
3016 else {
3017 if (quote) len++;
3018 if (arraynum(array)!=0) len=arraynum(array)*12-1;
3019 if (quote) len++;
3020 }
3021 break;
3022 case NDARRAY: case NDAFUNC:
3023 array=*(struct narray **)po;
3024 if (array==NULL) break;
3025 else {
3026 if (quote) len++;
3027 if (arraynum(array)!=0) len=arraynum(array)*24-1;
3028 if (quote) len++;
3029 }
3030 break;
3031 case NSARRAY: case NSAFUNC:
3032 array=*(struct narray **)po;
3033 if (array==NULL) break;
3034 else {
3035 if (quote) len++;
3036 for (k=0;k<arraynum(array);k++) {
3037 if (k!=0) len+=1;
3038 bval=*(char **)arraynget(array,k);
3039 for (i=0;bval[i]!='\0';i++) {
3040 if ((bval[i]=='\'') && quote) len+=3;
3041 len++;
3042 }
3043 }
3044 if (quote) len++;
3045 }
3046 break;
3047 case NENUM:
3048 len+=strlen(((char **)arglist)[*(int *)po]);
3049 break;
3050 }
3051 if (cr) len++;
3052 if ((s=memalloc(len+1))==NULL) return NULL;
3053 j=0;
3054 switch (type) {
3055 case NBOOL: case NBFUNC:
3056 if (*(int *)po) bval="true";
3057 else bval="false";
3058 j+=sprintf(s+j,"%s",bval);
3059 break;
3060 case NCHAR: case NCFUNC:
3061 j+=sprintf(s+j,"%c",*(char *)po);
3062 break;
3063 case NINT: case NIFUNC:
3064 j+=sprintf(s+j,"%d",*(int *)po);
3065 break;
3066 case NDOUBLE: case NDFUNC:
3067 j+=sprintf(s+j,"%.15e",*(double *)po);
3068 break;
3069 case NSTR: case NSFUNC: case NOBJ:
3070 if (*(char **)po==NULL) break;
3071 else {
3072 bval=*(char **)po;
3073 if (quote) j+=sprintf(s+j,"'");
3074 for (i=0;bval[i]!='\0';i++) {
3075 if ((bval[i]=='\'') && quote) j+=sprintf(s+j,"'\\''");
3076 else j+=sprintf(s+j,"%c",bval[i]);
3077 }
3078 if (quote) j+=sprintf(s+j,"'");
3079 }
3080 break;
3081 case NIARRAY: case NIAFUNC:
3082 array=*(struct narray **)po;
3083 if (array==NULL) break;
3084 else {
3085 if (quote) j+=sprintf(s+j,"'");
3086 for (k=0;k<arraynum(array);k++) {
3087 if (k!=0) j+=sprintf(s+j," %d",*(int *)arraynget(array,k));
3088 else j+=sprintf(s+j,"%d",*(int *)arraynget(array,k));
3089 }
3090 if (quote) j+=sprintf(s+j,"'");
3091 }
3092 break;
3093 case NDARRAY: case NDAFUNC:
3094 array=*(struct narray **)po;
3095 if (array==NULL) break;
3096 else {
3097 if (quote) j+=sprintf(s+j,"'");
3098 for (k=0;k<arraynum(array);k++) {
3099 if (k!=0) j+=sprintf(s+j," %.15e",*(double *)arraynget(array,k));
3100 else j+=sprintf(s+j,"%.15e",*(double *)arraynget(array,k));
3101 }
3102 if (quote) j+=sprintf(s+j,"'");
3103 }
3104 break;
3105 case NSARRAY: case NSAFUNC:
3106 array=*(struct narray **)po;
3107 if (array==NULL) break;
3108 else {
3109 if (quote) j+=sprintf(s+j,"'");
3110 for (k=0;k<arraynum(array);k++) {
3111 if (k!=0) j+=sprintf(s+j," ");
3112 bval=*(char **)arraynget(array,k);
3113 for (i=0;bval[i]!='\0';i++) {
3114 if ((bval[i]=='\'') && quote) j+=sprintf(s+j,"'\\''");
3115 else j+=sprintf(s+j,"%c",bval[i]);
3116 }
3117 }
3118 if (quote) j+=sprintf(s+j,"'");
3119 }
3120 break;
3121 case NENUM:
3122 j+=sprintf(s+j,"%s",((char **)arglist)[*(int *)po]);
3123 break;
3124 }
3125 if (cr) {
3126 s[j]='\n';
3127 j++;
3128 }
3129 s[j]='\0';
3130 return s;
3131 }
3132
getargument(int type,char * arglist,char * val,int * argc,char *** rargv)3133 int getargument(int type,char *arglist,char *val,int *argc,
3134 char ***rargv)
3135 {
3136 struct narray *array;
3137 int len,alp;
3138 char *list,*s,*s2;
3139 int vi;
3140 double vd;
3141 char **argv,*p;
3142 int rcode;
3143 char *code;
3144 int i,err;
3145 double memory[MEMORYNUM];
3146 char memorystat[MEMORYNUM];
3147 char **enumlist;
3148 char *oname,*os;
3149 int olen;
3150 struct objlist *obj2;
3151
3152 array=NULL;
3153 argv=NULL;
3154 if (arg_add(&argv,NULL)==NULL) goto errexit;
3155 s2=NULL;
3156 alp=0;
3157
3158 if (val==NULL) {
3159 *argc=getargc(argv);
3160 *rargv=argv;
3161 return 0;
3162 }
3163 list=val;
3164 err=-1;
3165 if (type==NENUM) {
3166 enumlist=(char **)arglist;
3167 arglist="s";
3168 }
3169 while (TRUE) {
3170 if ((arglist!=NULL)
3171 && ((strcmp0(arglist+alp,"s")==0) || (strcmp0(arglist+alp,"o")==0))) {
3172 if (list[0]=='\0') {
3173 s=NULL;
3174 len=0;
3175 alp++;
3176 } else {
3177 s=list;
3178 len=strlen(list);
3179 list+=len;
3180 }
3181 } else {
3182 s=getitok(&list,&len," \t\n\r");
3183 for (;(list[0]!='\0') && (strchr(" \t\n\r",list[0])!=NULL);list++);
3184 }
3185 if (s==NULL) break;
3186 memfree(s2);
3187 if ((s2=memalloc(len+1))==NULL) goto errexit;
3188 strncpy(s2,s,len);
3189 s2[len]='\0';
3190 if ((arglist!=NULL) && (arglist[alp]=='\0')) {
3191 err=1;
3192 goto errexit;
3193 }
3194 if (arglist==NULL) {
3195 if ((p=memalloc(strlen(s2)+1))==NULL) goto errexit;
3196 strcpy(p,s2);
3197 if (arg_add(&argv,p)==NULL) goto errexit;
3198 } else if (arglist[alp]=='o') {
3199 if (arglist[1]=='a') {
3200 err=3;
3201 goto errexit;
3202 }
3203 os=s2;
3204 if ((oname=getitok2(&os,&olen,":"))==NULL) {
3205 err=3;
3206 goto errexit;
3207 }
3208 obj2=chkobject(oname);
3209 memfree(oname);
3210 if ((obj2==NULL) || (os[0]!=':')) {
3211 err=3;
3212 goto errexit;
3213 }
3214 for (i=1;
3215 (os[i]!='\0')&&(isalnum(os[i])||(strchr("_^@!+-",os[i])!=NULL));i++);
3216 if (os[i]!='\0') {
3217 err=3;
3218 goto errexit;
3219 }
3220 if ((p=memalloc(strlen(s2)+1))==NULL) goto errexit;
3221 strcpy(p,s2);
3222 if (arg_add(&argv,p)==NULL) goto errexit;
3223 } else if (arglist[alp]=='s') {
3224 if (arglist[1]=='a') {
3225 if (array==NULL) {
3226 if ((array=arraynew(sizeof(char *)))==NULL) goto errexit;
3227 }
3228 if (arrayadd2(array,&s2)==NULL) goto errexit;
3229 } else {
3230 if ((p=memalloc(strlen(s2)+1))==NULL) goto errexit;
3231 strcpy(p,s2);
3232 if (arg_add(&argv,p)==NULL) goto errexit;
3233 }
3234 } else if ((arglist[alp]=='i') || (arglist[alp]=='d')) {
3235 rcode=mathcode(s2,&code,NULL,NULL,NULL,NULL,
3236 FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE);
3237 if (rcode!=MCNOERR) {
3238 err=3;
3239 goto errexit;
3240 }
3241 for (i=0;i<MEMORYNUM;i++) {memory[i]=0;memorystat[i]=MNOERR;}
3242 rcode=calculate(code,1,
3243 0,MNOERR,0,MNOERR,0,MNOERR,
3244 0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3245 NULL,NULL,
3246 memory,memorystat,
3247 NULL,NULL,
3248 NULL,NULL,
3249 NULL,NULL,NULL,
3250 NULL,NULL,NULL,0,NULL,NULL,NULL,0,&vd);
3251 memfree(code);
3252 if (rcode!=MNOERR) {
3253 err=3;
3254 goto errexit;
3255 }
3256 if (arglist[alp]=='i') {
3257 if (arglist[1]=='a') {
3258 vi=nround(vd);
3259 if (array==NULL) {
3260 if ((array=arraynew(sizeof(int)))==NULL) goto errexit;
3261 }
3262 if (arrayadd(array,&vi)==NULL) goto errexit;
3263 } else {
3264 if ((p=memalloc(sizeof(int)))==NULL) goto errexit;
3265 *(int *)(p)=nround(vd);
3266 if (arg_add(&argv,p)==NULL) goto errexit;
3267 }
3268 } else {
3269 if (arglist[1]=='a') {
3270 if (array==NULL) {
3271 if ((array=arraynew(sizeof(double)))==NULL) goto errexit;
3272 }
3273 if (arrayadd(array,&vd)==NULL) goto errexit;
3274 } else {
3275 if ((p=memalloc(sizeof(double)))==NULL) goto errexit;
3276 *(double *)(p)=vd;
3277 if (arg_add(&argv,p)==NULL) goto errexit;
3278 }
3279 }
3280 } else if (arglist[alp]=='b') {
3281 if ((strcmp0("T",s2)==0)
3282 || (strcmp0("True",s2)==0)
3283 || (strcmp0("TRUE",s2)==0)
3284 || (strcmp0("t",s2)==0)
3285 || (strcmp0("true",s2)==0)) vi=TRUE;
3286 else if ((strcmp0("F",s2)==0)
3287 || (strcmp0("False",s2)==0)
3288 || (strcmp0("FALSE",s2)==0)
3289 || (strcmp0("f",s2)==0)
3290 || (strcmp0("false",s2)==0)) vi=FALSE;
3291 else {
3292 err=3;
3293 goto errexit;
3294 }
3295 if (arglist[1]=='a') {
3296 err=3;
3297 goto errexit;
3298 } else {
3299 if ((p=memalloc(sizeof(int)))==NULL) goto errexit;
3300 *(int *)(p)=vi;
3301 if (arg_add(&argv,p)==NULL) goto errexit;
3302 }
3303 } else if (arglist[alp]=='c') {
3304 if (strlen(s2)>1) {
3305 err=3;
3306 goto errexit;
3307 }
3308 vi=s2[0];
3309 if (arglist[1]=='a') {
3310 err=3;
3311 goto errexit;
3312 } else {
3313 if ((p=memalloc(sizeof(int)))==NULL) goto errexit;
3314 *(int *)(p)=vi;
3315 if (arg_add(&argv,p)==NULL) goto errexit;
3316 }
3317 } else {
3318 err=3;
3319 goto errexit;
3320 }
3321 if ((arglist!=NULL) && (arglist[1]!='a')) alp++;
3322 }
3323 if ((arglist!=NULL) && (arglist[1]=='a')) {
3324 if (arg_add(&argv,array)==NULL) goto errexit;
3325 } else {
3326 if ((arglist!=NULL) && (arglist[alp]!='\0')) {
3327 err=2;
3328 goto errexit;
3329 }
3330 }
3331 if (type==NENUM) {
3332 if (argv[0]==NULL) {
3333 err=3;
3334 goto errexit;
3335 }
3336 for (i=0;enumlist[i]!=NULL;i++)
3337 if (strcmp0(enumlist[i],argv[0])==0) break;
3338 if (enumlist[i]==NULL) {
3339 err=3;
3340 goto errexit;
3341 }
3342 memfree(argv[0]);
3343 if ((p=memalloc(sizeof(int)))==NULL) goto errexit;
3344 *(int *)(p)=i;
3345 argv[0]=p;
3346 }
3347
3348 *argc=getargc(argv);
3349 memfree(s2);
3350 *rargv=argv;
3351 return 0;
3352
3353 errexit:
3354 arrayfree(array);
3355 memfree(s2);
3356 arg_del(argv);
3357 *argc=-1;
3358 *rargv=NULL;
3359 return err;
3360 }
3361
freeargument(int type,char * arglist,int argc,char ** argv,int full)3362 void freeargument(int type,char *arglist,int argc,char **argv,int full)
3363 {
3364 int i;
3365
3366 if (argv!=NULL) {
3367 if (arglist==NULL) {
3368 for (i=0;i<argc;i++) memfree(argv[i]);
3369 memfree(argv);
3370 } else if (full) {
3371 if ((type!=NENUM) && (argc>0)
3372 && (arglist[0]!='\0') && (arglist[1]=='a')) {
3373 if ((arglist[0]=='i') || (arglist[0]=='d'))
3374 arrayfree((struct narray *)(argv[0]));
3375 else if (arglist[0]=='s')
3376 arrayfree2((struct narray *)(argv[0]));
3377 } else for (i=0;i<argc;i++) memfree(argv[i]);
3378 memfree(argv);
3379 } else {
3380 if ((type==NENUM) || (arglist[0]=='\0') || (arglist[1]!='a')) {
3381 for (i=0;i<argc;i++)
3382 if ((type==NENUM) || (strchr("bcid",arglist[i])!=NULL))
3383 memfree(argv[i]);
3384 }
3385 memfree(argv);
3386 }
3387 }
3388 }
3389
isobject(char ** s)3390 int isobject(char **s)
3391 {
3392 char *po;
3393 int i;
3394
3395 po=*s;
3396 for (i=0;(po[i]!='\0')&&(isalnum(po[i])||(strchr("_@",po[i])!=NULL));i++);
3397 if (po[i]!=':') return FALSE;
3398 for (i++;(po[i]!='\0')&&(isalnum(po[i])||(strchr("_./-,@!.",po[i])!=NULL));
3399 i++);
3400 if (po[i]!=':') return FALSE;
3401 if (po[i+1]=='\0') return FALSE;
3402 for (i++;(po[i]!='\0')&&(isalnum(po[i])||(strchr("_@",po[i])!=NULL));i++);
3403 *s=po+i;
3404 return TRUE;
3405 }
3406
schkobjfield(struct objlist * obj,int id,char * field,char * arg,char ** valstr,int limittype,int cr,int quote)3407 int schkobjfield(struct objlist *obj,int id,char *field,char *arg,
3408 char **valstr,int limittype,int cr,int quote)
3409 {
3410 int err;
3411 char *val;
3412 int argc2,type;
3413 char *arglist;
3414 char **argv2;
3415 char value[8];
3416 char *po;
3417
3418 *valstr=NULL;
3419 val=arg;
3420 if (chkobjfield(obj,field)==-1) return -1;
3421 argv2=NULL;
3422 type=chkobjfieldtype(obj,field);
3423 if (limittype) {
3424 if ((type>NVFUNC) && (type!=NSFUNC) && (type!=NSAFUNC)) {
3425 return -1;
3426 }
3427 }
3428 if (type>=NVFUNC) {
3429 arglist=chkobjarglist(obj,field);
3430 } else {
3431 arglist="";
3432 type=NVOID;
3433 }
3434 po=value;
3435 err=getargument(type,arglist,val,&argc2,&argv2);
3436 if (err==1) return ERROEXTARG;
3437 else if (err==2) return ERROSMLARG;
3438 else if (err==3) return ERROVALUE;
3439 else if (err!=0) return -1;
3440 if (getobj(obj,field,id,argc2,argv2,po)==-1) err=4;
3441 freeargument(type,arglist,argc2,argv2,TRUE);
3442 if (err==0) {
3443 *valstr=getvaluestr(obj,field,po,cr,quote);
3444 if (*valstr==NULL) return -1;
3445 return 0;
3446 } else return -2;
3447 }
3448
sgetobjfield(struct objlist * obj,int id,char * field,char * arg,char ** valstr,int limittype,int cr,int quote)3449 int sgetobjfield(struct objlist *obj,int id,char *field,char *arg,
3450 char **valstr,int limittype,int cr,int quote)
3451 {
3452 int err;
3453 char *val;
3454 int argc2,type;
3455 char *arglist;
3456 char **argv2;
3457 char value[8];
3458 char *po;
3459
3460 *valstr=NULL;
3461 val=arg;
3462 if (getobjfield(obj,field)==-1) return -1;
3463 argv2=NULL;
3464 type=chkobjfieldtype(obj,field);
3465 if (limittype) {
3466 if ((type>NVFUNC) && (type!=NSFUNC) && (type!=NSAFUNC)) {
3467 return -1;
3468 }
3469 }
3470 if (type>=NVFUNC) {
3471 arglist=chkobjarglist(obj,field);
3472 } else {
3473 arglist="";
3474 type=NVOID;
3475 }
3476 po=value;
3477 err=getargument(type,arglist,val,&argc2,&argv2);
3478 if (err==1) {
3479 error22(obj,ERROEXTARG,field,arg);
3480 return ERROEXTARG;
3481 } else if (err==2) {
3482 error22(obj,ERROSMLARG,field,arg);
3483 return ERROSMLARG;
3484 } else if (err==3) {
3485 error22(obj,ERROVALUE,field,arg);
3486 return ERROVALUE;
3487 } else if (err!=0) return -1;
3488 if (getobj(obj,field,id,argc2,argv2,po)==-1) err=4;
3489 freeargument(type,arglist,argc2,argv2,TRUE);
3490 if (err==0) {
3491 *valstr=getvaluestr(obj,field,po,cr,quote);
3492 if (*valstr==NULL) return -1;
3493 return 0;
3494 } else return -2;
3495 }
3496
schkfield(struct objlist * obj,int id,char * arg,char ** valstr,int limittype,int cr,int quote)3497 int schkfield(struct objlist *obj,int id,char *arg,char **valstr,
3498 int limittype,int cr,int quote)
3499 {
3500 int err;
3501 char *field;
3502 int len;
3503 char *s;
3504
3505 s=arg;
3506 *valstr=NULL;
3507 if ((s==NULL)
3508 || (strchr(":= \t",s[0])!=NULL)
3509 || ((field=getitok2(&s,&len,":= \t"))==NULL)) {
3510 if (len==-1) return -1;
3511 return ERRFIELD;
3512 }
3513 if (s[0]!='\0') s++;
3514 while ((s[0]==' ') || (s[0]=='\t')) s++;
3515 err=schkobjfield(obj,id,field,s,valstr,limittype,cr,quote);
3516 memfree(field);
3517 return err;
3518 }
3519
sgetfield(struct objlist * obj,int id,char * arg,char ** valstr,int limittype,int cr,int quote)3520 int sgetfield(struct objlist *obj,int id,char *arg,char **valstr,
3521 int limittype,int cr,int quote)
3522 {
3523 int err;
3524 char *field;
3525 int len;
3526 char *s;
3527
3528 s=arg;
3529 *valstr=NULL;
3530 if ((s==NULL)
3531 || (strchr(":= \t",s[0])!=NULL)
3532 || ((field=getitok2(&s,&len,":= \t"))==NULL)) {
3533 if (len==-1) return -1;
3534 error2(obj,ERRFIELD,arg);
3535 return ERRFIELD;
3536 }
3537 if (s[0]!='\0') s++;
3538 while ((s[0]==' ') || (s[0]=='\t')) s++;
3539 err=sgetobjfield(obj,id,field,s,valstr,limittype,cr,quote);
3540 memfree(field);
3541 return err;
3542 }
3543
sgetobj(char * arg,int limittype,int cr,int quote)3544 struct narray *sgetobj(char *arg,int limittype,int cr,int quote)
3545 {
3546 struct objlist *obj;
3547 int i,anum,*id;
3548 struct narray iarray,*sarray;
3549 char *valstr;
3550
3551 arrayinit(&iarray,sizeof(int));
3552 if ((sarray=arraynew(sizeof(char *)))==NULL) return NULL;
3553 if (chkobjilist2(&arg,&obj,&iarray,TRUE)) {
3554 arrayfree2(sarray);
3555 return NULL;
3556 }
3557 anum=arraynum(&iarray);
3558 id=arraydata(&iarray);
3559 for (i=0;i<anum;i++) {
3560 if (schkfield(obj,id[i],arg,&valstr,limittype,cr,quote)!=0) {
3561 arraydel(&iarray);
3562 arrayfree2(sarray);
3563 return NULL;
3564 }
3565 if (arrayadd(sarray,&valstr)==NULL) {
3566 arraydel(&iarray);
3567 arrayfree2(sarray);
3568 return NULL;
3569 }
3570 }
3571 arraydel(&iarray);
3572 return sarray;
3573 }
3574
sputobjfield(struct objlist * obj,int id,char * field,char * arg)3575 int sputobjfield(struct objlist *obj,int id,char *field,char *arg)
3576 {
3577 char *val;
3578 char *arglist;
3579 int err,type;
3580 int argc2;
3581 char **argv2;
3582
3583 val=arg;
3584 if (getobjfield(obj,field)==-1) return -1;
3585 if ((type=chkobjfieldtype(obj,field))<NVFUNC) {
3586 arglist=chkobjarglist(obj,field);
3587 } else {
3588 arglist="";
3589 type=NVOID;
3590 }
3591 err=getargument(type,arglist,val,&argc2,&argv2);
3592 if (err==1) {
3593 error22(obj,ERROEXTARG,field,arg);
3594 return ERROEXTARG;
3595 } else if (err==2) {
3596 error22(obj,ERROSMLARG,field,arg);
3597 return ERROSMLARG;
3598 } else if (err==3) {
3599 error22(obj,ERROVALUE,field,arg);
3600 return ERROVALUE;
3601 } else if (err!=0) return -1;
3602 if (argv2!=NULL) {
3603 if (putobj(obj,field,id,argv2[0])==-1) err=4;
3604 } else {
3605 if (putobj(obj,field,id,NULL)==-1) err=4;
3606 }
3607 if (err==0) {
3608 freeargument(type,arglist,argc2,argv2,FALSE);
3609 return 0;
3610 } else {
3611 freeargument(type,arglist,argc2,argv2,TRUE);
3612 return -2;
3613 }
3614 }
3615
sputfield(struct objlist * obj,int id,char * arg)3616 int sputfield(struct objlist *obj,int id,char *arg)
3617 {
3618 char *field;
3619 char *s;
3620 int err;
3621 int len;
3622
3623 s=arg;
3624 if ((s==NULL)
3625 || (strchr(":=",s[0])!=NULL)
3626 || ((field=getitok2(&s,&len,":="))==NULL)) {
3627 if (len==-1) return -1;
3628 error2(obj,ERRFIELD,arg);
3629 return ERRFIELD;
3630 }
3631 if (s[0]!='\0') s++;
3632 err=sputobjfield(obj,id,field,s);
3633 memfree(field);
3634 return err;
3635 }
3636
sputobj(char * arg)3637 int sputobj(char *arg)
3638 {
3639 struct objlist *obj;
3640 int i,anum,*id;
3641 struct narray iarray;
3642
3643 arrayinit(&iarray,sizeof(int));
3644 if (getobjilist2(&arg,&obj,&iarray,TRUE)) return -1;
3645 anum=arraynum(&iarray);
3646 id=arraydata(&iarray);
3647 for (i=0;i<anum;i++)
3648 if (sputfield(obj,id[i],arg)!=0) {
3649 arraydel(&iarray);
3650 return -1;
3651 }
3652 arraydel(&iarray);
3653 return 0;
3654 }
3655
sexeobjfield(struct objlist * obj,int id,char * field,char * arg)3656 int sexeobjfield(struct objlist *obj,int id,char *field,char *arg)
3657 {
3658 char *val;
3659 int err,type;
3660 int argc2;
3661 char *arglist;
3662 char **argv2;
3663 int rcode;
3664
3665 val=arg;
3666 if (getobjfield(obj,field)==-1) return -1;
3667 if ((type=chkobjfieldtype(obj,field))>=NVFUNC) {
3668 arglist=chkobjarglist(obj,field);
3669 } else {
3670 arglist="";
3671 type=NVOID;
3672 }
3673 err=getargument(type,arglist,val,&argc2,&argv2);
3674 if (err==1) {
3675 error22(NULL,ERROEXTARG,field,arg);
3676 return -1;
3677 } else if (err==2) {
3678 error22(obj,ERROSMLARG,field,arg);
3679 return -1;
3680 } else if (err==3) {
3681 error22(obj,ERROVALUE,field,arg);
3682 return -1;
3683 } else if (err!=0) return -1;
3684 rcode=exeobj(obj,field,id,argc2,argv2);
3685 freeargument(type,arglist,argc2,argv2,TRUE);
3686 return rcode;
3687 }
3688
sexefield(struct objlist * obj,int id,char * arg)3689 int sexefield(struct objlist *obj,int id,char *arg)
3690 {
3691 char *field;
3692 int rcode;
3693 int len;
3694 char *s;
3695
3696 s=arg;
3697 if ((s==NULL)
3698 || (strchr(":= \t",s[0])!=NULL)
3699 || ((field=getitok2(&s,&len,":= \t"))==NULL)) {
3700 if (len==-1) return -1;
3701 error2(obj,ERRFIELD,arg);
3702 return -1;
3703 }
3704 if (s[0]!='\0') s++;
3705 while ((s[0]==' ') || (s[0]=='\t')) s++;
3706 rcode=sexeobjfield(obj,id,field,s);
3707 memfree(field);
3708 return rcode;
3709 }
3710
sexeobj(char * arg)3711 int sexeobj(char *arg)
3712 {
3713 struct objlist *obj;
3714 int i,anum,*id;
3715 struct narray iarray;
3716 int rcode;
3717
3718 arrayinit(&iarray,sizeof(int));
3719 if (getobjilist2(&arg,&obj,&iarray,TRUE)) return -1;
3720 anum=arraynum(&iarray);
3721 id=arraydata(&iarray);
3722 rcode=0;
3723 for (i=0;i<anum;i++) {
3724 if ((rcode=sexefield(obj,id[i],arg))==-1) {
3725 arraydel(&iarray);
3726 return -1;
3727 }
3728 }
3729 arraydel(&iarray);
3730 return rcode;
3731 }
3732
getuniqname(struct objlist * obj,char * prefix,char sep)3733 char *getuniqname(struct objlist *obj,char *prefix,char sep)
3734 {
3735 int i,j,len;
3736 char *iname;
3737 char *inst;
3738 char *name;
3739 int c[10];
3740
3741 if (chkobjoffset(obj,"name")==-1) return NULL;
3742 if (prefix==NULL) len=0;
3743 else len=strlen(prefix);
3744 if (sep!='\0') len++;
3745 if ((name=memalloc(len+11))==NULL) return NULL;
3746 for (i=0;i<10;i++) c[i]=0;
3747 while (TRUE) {
3748 match:
3749 i=0;
3750 while (TRUE) {
3751 c[i]++;
3752 if (c[i]==26) {
3753 c[i]=1;
3754 i++;
3755 if (i==10) return NULL;
3756 } else break;
3757 }
3758 for (i=9;i>=0;i--) if (c[i]!=0) break;
3759 if (prefix!=NULL) strcpy(name,prefix);
3760 if (sep!='\0') name[len-1]=sep;
3761 for (j=len;j<=len+i;j++) name[j]=c[i-j+len]-1+'a';
3762 name[j]='\0';
3763 for (i=0;i<=obj->lastinst;i++) {
3764 if ((inst=chkobjinst(obj,i))==NULL) return NULL;
3765 if (_getobj(obj,"name",inst,&iname)==-1) return NULL;
3766 if ((iname!=NULL) && (strcmp0(iname,name)==0)) goto match;
3767 }
3768 break;
3769 }
3770 return name;
3771 }
3772