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