source: branches/stable/AISC_COM/AISC/aisc_server.pa

Last change on this file was 16763, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.9 KB
Line 
1# set to 1 to trace object creation/destruction
2CREATE $(TRACE) = 0
3
4GOTO main
5
6FUNCTION return_ifnot conds,result
7    IF $(conds) ~ &
8        P if (!($(conds:# && =))) return $(INIT|$(result));
9    ENDIF
10RETURN
11FUNCTION index_or_return index,return
12    IF $(index) !~ #
13        P int index = aisc_talking_get_index(0, $(index)); /* index_or_return $(return) */
14        SET $(return) return $(return);
15        P if (aisc_server_error) $(return: ;=;)
16    ENDIF
17RETURN
18
19FUNCTION define_callback a,type,func
20    CONST $(a) # releative key
21    CONST $(type) # function type (get, set etc.)
22    CONST $(func) # function name
23
24    CREATE $(num) = $(+ $(a)+$(KEYC))
25    CREATE $(cb) $(type)_list[$(num)]
26    # $(cb) contains name of callback variable
27
28    IF $($(cb))
29        IF $($(cb)) ~ 0
30        ELSE
31            ERROR Number $(KEYC) for '$(func)' already in use by '$($(cb))'
32        ENDIF
33    ELSE
34        ERROR Invalid number $(KEYC) for '$(func)'. Increase MAX_KEY to $(num) in $(argv[2])
35    ENDIF
36    SET $($(cb)) = $(func)
37RETURN
38
39FUNCTION accessors struct,a,c
40    # struct = struct/member name
41    # a = relative key (int)
42    # c = conditions
43
44    CONST $(struct)
45    CONST $(a)
46    CONST $(c)
47
48    CREATE $(su) $(setup)
49    CREATE $(ac) $(access)
50    CREATE $(in) $(index)
51
52    CONST $(su)
53    CONST $(ac)
54    CONST $(in)
55
56    CREATE $(type)
57    CREATE $(member)
58    CREATE $(conds)
59    CREATE $(fun)
60    CREATE $(funtype)
61    CREATE $(null)
62
63    FOR $({/KEY)
64        SET $(member) $(struct)$(KEY)
65        SET $(conds) $(c)
66        SET $(setup) $(su)
67
68        IF $(TYPE) = dllh
69            SET $(fun) get_$(member)PRED
70            CALL define_callback $(a),get,$(fun)
71            IF $(extern_$(fun))
72            ELSE
73                P static $(maintype) *$(fun)(const $(maintype) *THIS) {
74                INDENT +1
75                    CALL return_ifnot $(conds),NULp
76                    #P return ($(maintype) *)$(ac)previous;
77                    P return $(ac)previous;
78                INDENT -1
79                P }
80            ENDIF
81
82            SET $(fun) get_$(member)NEXT
83            CALL define_callback $(+ $(a)+1),get,$(fun)
84            IF $(extern_$(fun))
85            ELSE
86                P static $(maintype) *$(fun)(const $(maintype) *THIS) {
87                INDENT +1
88                    CALL return_ifnot $(conds),NULp
89                    #P return ($(maintype) *)$(ac)next;
90                    P return $(ac)next;
91                INDENT -1
92                P }
93            ENDIF
94
95            PUSH
96            CREATE $(subadd) $(+ 2+$(+ $(a)+$(KEYC)))
97            SET $(access) $(ac)$(IDENT).
98            MOVETO $(/AISC/DATA/STRUCT.dll_header)
99            GOSUB accessors $(member),$(subadd),$(conds)
100            POP
101            CONTINUE
102        ENDIF
103 
104        SET $(index) $(in)
105        SET $(access) $(ac)$(IDENT)
106
107        IF $(REF) ~ *
108            SET $(conds) $(conds) && $(access)
109            SET $(index) $(SIZE:THIS->=$(ac))
110            IF $(REF) ~ o,d,l,r
111                SET $(type) $(TYPE) *
112            ELSE
113                SET $(type) $(TYPE)
114            ENDIF
115            SET $(setup) $(setup)if (!$(access)) $(access) = ($(type)*)calloc(sizeof($(type)),$(index));$n
116            SET $(access) $(access)[index]
117        ELSEIF $(REF) ~ v
118            SET $(index) $(SIZE:THIS->=$(ac))
119            SET $(access) $(access)[index]
120        ENDIF
121
122        IF $(REF) ~ s
123            IF $(REF) ~ o,l,r
124                SET $(conds) $(conds) && $(access)
125                SET $(setup) $(setup)if (!$(access)) $(access) = create_$(TYPE)();$n
126                SET $(access) $(access)->
127            ELSEIF $(REF) ~ i
128                SET $(access) $(access).
129            ENDIF
130
131            PUSH
132            CREATE $(subadd) = $(+ $(a)+$(KEYC))
133            MOVETO $(/AISC/DATA/STRUCT.$(TYPE))
134            CALL accessors $(member),$(subadd),$(conds)
135            POP
136            CONTINUE
137        ENDIF
138
139        IF $(REF) ~ o,d
140            IF $(ACC) !~ c
141            ELSE
142                # CREATE FUNCTIONS
143                SET $(fun) create_$(member)
144                CALL define_callback $(a),create,$(fun)
145                IF $(extern_$(fun))
146                ELSE
147                    P static $(TYPE) *$(fun)($(maintype) *THIS) {
148                    INDENT +1
149                        CALL return_ifnot $(conds),NULp
150                        CALL index_or_return $(index),NULp
151                        P $(TYPE) *obj = create_$(TYPE)();
152                        P if (obj) {
153                        INDENT +1
154                            P aisc_make_sets((long *)obj);
155                            P if (aisc_server_error) {
156                            INDENT +1
157                                P destroy_$(TYPE)(obj);
158                                P obj = NULp;
159                            INDENT -1
160                            P }
161                            P else {
162                            INDENT +1
163                                IF $(REF) ~ d
164                                    P aisc_server_error = aisc_link((dllpublic_ext*)&($(ac)p$(IDENT)), (dllheader_ext*)obj);
165                                ELSE
166                                    P if ($(access)) destroy_$(TYPE)($(access));
167                                    P $(access) = obj;
168                                ENDIF
169                            INDENT -1
170                            P }
171                        INDENT -1
172                        P }
173                        P return obj;
174                    INDENT -1
175                    P }
176                ENDIF
177
178                # COPY FUNCTIONS
179                SET $(fun) copy_$(member)
180                CALL define_callback $(a),copy,$(fun)
181                IF $(extern_$(fun))
182                ELSE
183                    P static $(TYPE) *$(fun)($(maintype) *THIS) {
184                    INDENT +1
185                        CALL return_ifnot $(conds),NULp
186                        CALL index_or_return $(index),NULp
187                        P trf_begin();
188                        P $(TYPE) *obj = copy_$(TYPE)($(access));
189                        P trf_commit(0);
190                        P if (obj) {
191                        INDENT +1
192                            P aisc_make_sets((long *)obj);
193                            P if (aisc_server_error) {
194                            INDENT +1
195                                P destroy_$(TYPE)(obj);
196                                P obj = NULp;
197                            INDENT -1
198                            P }
199                            P else {
200                            INDENT +1
201                                IF $(REF) ~ d
202                                    P aisc_server_error = aisc_link((dllpublic_ext*)&($(ac)p$(IDENT)), (dllheader_ext*)obj);
203                                ELSE
204                                    P if ($(access)) destroy_$(TYPE)($(access));
205                                    P $(access) = obj;
206                                ENDIF
207                            INDENT -1
208                            P }
209                        INDENT -1
210                        P }
211                        P return obj;
212                    INDENT -1
213                    P }
214                ENDIF
215            ENDIF
216            # FIND FUNCTIONS
217            IF $(ACC) !~ f
218            ELSEIF $(REF) ~ d
219                SET $(fun) find_$(member)
220                CALL define_callback $(a),find,$(fun)
221                IF $(extern_$(fun))
222                ELSE
223                    P static $(TYPE) *$(fun)(const $(maintype) *THIS, const char *key) {
224                    INDENT +1
225                        CALL return_ifnot $(conds),NULp
226                        P $(TYPE) *obj = ($(TYPE)*)aisc_read_hash((aisc_hash_node**)$(ac)p$(IDENT).hash, key);
227                        P return obj;
228                    INDENT -1
229                    P }
230                ENDIF
231            ENDIF
232            # CNT FUNCTION
233            IF $(REF) ~ d
234                SET $(fun) get_$(member)_CNT
235                CALL define_callback $(+ $(a)+1),get,$(fun)
236                IF $(extern_$(fun))
237                ELSE
238                    P static int $(fun)(const $(maintype) *THIS) {
239                    INDENT +1
240                        CALL return_ifnot $(conds),0
241                        P return $(ac)p$(IDENT).cnt;
242                    INDENT -1
243                    P }
244                ENDIF
245            ENDIF
246        ELSE
247            # not $(REF) ~ o,d
248
249            # SET FUNCTIONS
250            IF $(ACC) !~ w
251            ELSEIF $(REF) ~ $(v)
252                CALL define_callback $(a),set,$(IDENT)
253                IF $(extern_$(IDENT))
254                ELSE
255                    OUT import # Generate Prototypes for import
256                    P extern int $1$(IDENT)($(maintype)*, $(TYPE:bytestring=bytestring *));
257                    OUT save
258                ENDIF
259            ELSE
260                SET $(fun) set_$(member)
261                CALL define_callback $(a),set,$(fun)
262                IF $(extern_$(fun))
263                ELSE
264                    IF $(REF) ~ o,l,r
265                        P static void $(fun)($(maintype) *THIS, const $(TYPE) *x) {
266                    ELSEIF $(REF) ~ t,e
267                        P static void $(fun)($(maintype) *THIS, $(TYPE:bytestring=const bytestring *) x) {
268                    ELSE
269                        ERROR UNKNOWN REF '$(REF|)' in $(STRUCT).$(TYPE)
270                    ENDIF
271                    INDENT +1
272                        CALL index_or_return $(index),
273                        P $(setup)$\
274                        IF $(TYPE) = aisc_string
275                            P freeset($(access), x);
276                        ELSEIF $(TYPE) = bytestring
277                            P if (x) {
278                                P $1freeset($(access).data, x->data);
279                                P $1$(access).size = x->size;
280                            P }
281                            P else {
282                                P $1freenull($(access).data);
283                                P $1$(access).size = 0;
284                            P }
285                        ELSE
286                            IF $(REF) ~ o
287                                P if ($(access)) destroy_$(TYPE)($(access));
288                            ENDIF
289                            P $(access) = x;
290                        ENDIF
291                    INDENT -1
292                    P }
293                ENDIF
294            ENDIF
295        ENDIF
296
297        # GET FUNCTIONS
298        IF $(ACC) !~ r
299        ELSEIF $(REF) ~ $(v)
300            IF $(extern_$(IDENT))
301                CALL define_callback $(a),get,$(IDENT)
302            ELSE
303                IF $(IDENT) = aisc_get_keystring
304                    # special cast for aisc_get_keystring
305                    CALL define_callback $(a),get,(const char*(*)(int*))$(IDENT)
306                ELSE
307                    # explicit cast to overloaded function type before casting to void
308                    CALL define_callback $(a),get,($(TYPE:bytestring=bytestring *)(*)(const $(maintype)*))$(IDENT)
309                ENDIF
310                OUT import      # Generate Prototypes for import
311                P extern $(TYPE:bytestring=bytestring *) $(IDENT)(const $(maintype)*);
312                OUT save
313            ENDIF
314        ELSE
315            CALL define_callback $(a),get,get_$(member)
316            IF $(extern_get_$(member))
317            ELSE
318                P static $\
319                IF $(REF) ~ o,l,r,d
320                    SET $(funtype) = const $(TYPE) *
321                ELSEIF $(REF) ~ e,t
322                    SET $(funtype) = $(TYPE:bytestring=const bytestring *:aisc_string=aisc_cstring)
323                ELSE
324                    ERROR UNKNOWN REF '$(REF|)' in $(STRUCT).$(TYPE)
325                ENDIF
326
327                # detect return type for return_ifnot and index_or_return below
328                IF $(funtype) ~ *
329                    SET $(null) = NULp
330                ELSE
331                    # note the trailing space on next line!
332                    SET $(funtype) = $(funtype)
333                    SET $(null) = 0
334                ENDIF
335                P $(funtype)get_$(member)(const $(maintype) *THIS) {
336
337                INDENT +1
338                    CALL return_ifnot $(conds),$(null)
339                    CALL index_or_return $(index),$(null)
340                    IF $(TYPE) = bytestring
341                        P return &($(access));
342                    ELSE
343                        P return $(access);
344                    ENDIF
345                INDENT -1
346                P }
347            ENDIF
348        ENDIF
349    ENDFOR
350RETURN
351
352FUNCTION accessor_table fun
353    P void *aisc_talking_functions_$(fun)_$(STRUCT)[] = {
354    INDENT +1
355        CREATE $(i)
356        CREATE $(cb)
357        CREATE $(zeros)
358        FOR $(i) = 0 TO $(MAX_KEY)
359            SET $(cb) = $($(fun)_list[$(i)])
360            IF $(cb) = 0
361                # collect multiple '0' to print them in one line
362                SET $(zeros) = $(zeros) NULp,
363            ELSE
364                IF $(zeros)!=
365                    P $(zeros)
366                    SET $(zeros)
367                ENDIF
368
369                IF $(cb) ~ /*
370                    SET $(cb) = $(cb:/*=,/*: ,/*=,/*:,/*=, /*)
371                ELSEIF $(cb) ~ //
372                    SET $(cb) = $(cb://=,//: ,//=,//:,//=, //)
373                ELSE
374                    SET $(cb) = $(cb),
375                ENDIF
376
377                P (void *)$(cb)
378            ENDIF
379        ENDFOR
380        IF $(zeros) !=
381            P $(zeros) NULp
382        ELSE
383            P NULp
384        ENDIF
385    INDENT -1
386    P };
387RETURN
388
389FUNCTION accessor_tables
390    CALL accessor_table get
391    CALL accessor_table set
392    CALL accessor_table create
393    CALL accessor_table find
394    CALL accessor_table copy
395    --
396RETURN
397
398FUNCTION build_accessors
399    # init callback tables
400    CREATE $(i) = 0
401    FOR $(i) = 0 TO $(MAX_KEY)
402        CREATE $(set_list[$(i)]) 0
403        CREATE $(get_list[$(i)]) 0
404        CREATE $(create_list[$(i)]) 0
405        CREATE $(find_list[$(i)]) 0
406        CREATE $(copy_list[$(i)]) 0
407    ENDFOR
408
409    #CREATE $(conds)
410    CREATE $(access)
411    CREATE $(maintype)
412    CREATE $(setup)
413    CREATE $(index) #
414
415    CREATE $(joined)
416
417    FOR $(STRUCT)
418        IF $(SKEY)
419            P // $(STRUCT) accessors
420            --
421
422            IF $(JOINED)
423            ELSE
424                FOR $(i) = 0 TO $(MAX_KEY)
425                    SET $(set_list[$(i)]) 0
426                    SET $(get_list[$(i)]) 0
427                    SET $(create_list[$(i)]) 0
428                    SET $(find_list[$(i)]) 0
429                    SET $(copy_list[$(i)]) 0
430                ENDFOR
431            ENDIF
432            #SET $(conds) = #
433            SET $(access) THIS->
434            SET $(maintype) $(STRUCT)
435            # 'setup' can not be transformed to parameter, cause it is
436            # assigned sth containing ,; etc. so we need to use a global here :-(
437            SET $(setup)
438            SET $(index) #
439            GOSUB accessors $(SKEY)_,0,#
440            --
441
442            IF $(JOIN_NEXT)
443                SET $(joined) = $(joined) $(STRUCT)
444            ELSE
445                P // $(joined) $(STRUCT) callback tables
446                SET $(joined) =
447                GOSUB accessor_tables
448            ENDIF
449        ENDIF
450    ENDFOR
451RETURN
452
453# --------------------------------------------------------------------------------
454
455FUNCTION init_structure,self,deref
456    CREATE $(member)
457    CREATE $(isloop)
458
459    FOR $({/TYPE)
460        SET $(member) $(self)$(deref)$(IDENT)
461        SET $(isloop) 0
462        IF $(REF) ~ $(v)
463        ELSE
464            IF $(REF) ~ v
465                SET $(isloop) 1
466                PMSTART
467                PM for (int index = 0; index < $(SIZE:THIS->=$(self)$(deref)); index++) {
468                INDENT +1
469                SET $(member) $(member)[index]
470            ENDIF
471            IF $(TYPE) = dllh
472                P $(member).key $|= KEY_$(OBJECT_KEY)_$(SKEY|COMMON);
473                PUSH
474                MOVETO $(/AISC/DATA/STRUCT.dll_header)
475                GOSUB init_structure,$(member),.
476                POP
477            ELSEIF $(REF) ~ o
478                # just a NULp pointer - no init necessary
479            ELSEIF $(REF) ~ d
480                PUSH
481                    SET $(member) = $(self)$(deref)p$(IDENT)
482                    MOVETO $(/AISC/DATA/STRUCT.$(TYPE))
483                    P $(member).parent $|= (dllheader_ext *)$(self);
484                    P $(member).key $|= KEY_$(OBJECT_KEY)_$(SKEY|SKEY_missing);
485                POP
486            ELSEIF $(REF) ~ s
487                IF $(REF) ~ i
488                    PUSH
489                    MOVETO $(/AISC/DATA/STRUCT.$(TYPE))
490                    GOSUB init_structure,$(member),.
491                    POP
492                ENDIF
493            ELSEIF $(REF) ~ t,e,l
494                IF $(IDENT) = key
495                    IF $(SKEY) !~ COMMON
496                        P $(member) $|= KEY_$(OBJECT_KEY)_$(SKEY|COMMON);
497                    ENDIF
498                ELSEIF $(INIT)
499                    IF $(TYPE) = aisc_string
500                        P $(member) $|= strdup($(INIT:THIS=$(self)));
501                    ELSE
502                        P $(member) $|= $(INIT:THIS=$(self));
503                    ENDIF
504                ENDIF
505            ELSE
506                ERROR UNKNOWN REF '$(REF|)' in $(STRUCT).$(TYPE)
507            ENDIF
508            IF $(isloop) = 1
509                INDENT -1
510                PM }
511                PMEND
512            ENDIF
513        ENDIF
514    ENDFOR
515RETURN
516
517FUNCTION build_init
518    P // ------------
519    P // constructors
520    --
521    P inline void alloc_err(const char *objectname) {
522    P $1aisc_server_errorf("Could not allocate '%s'", objectname);
523    P }
524    --
525   
526    FOR $(STRUCT)
527        IF $(extern_create_$(STRUCT))
528        ELSE
529            P $(STRUCT) *create_$(STRUCT)()$\
530            P  {
531            INDENT +1
532                P $(STRUCT) *o = ($(STRUCT)*)calloc(sizeof(*o), 1);
533                P if (!o) alloc_err("$(STRUCT)");
534                PMSTART
535                PM else {
536                INDENT +1
537                    GOSUB init_structure o,->
538                INDENT -1
539                PM }
540                PMEND
541                GOSUB trace "created $(STRUCT)"
542                P return o;
543            INDENT -1
544            P }
545        ENDIF
546        --
547    ENDFOR
548RETURN
549
550FUNCTION delete_structure,self,deref
551    CREATE $(member)
552    CREATE $(isloop)
553    CREATE $(isinif)
554    CREATE $(start)
555
556    FOR $({/TYPE)
557        SET $(member) $(self)$(deref)$(IDENT)
558        SET $(isloop) 0
559        SET $(isinif) 0
560
561        IF $(DESTROY)
562            P $(DESTROY:THIS=obj);
563        ELSEIF $(REF) ~ $(v)
564            # virtual function
565        ELSE
566            IF $(REF) ~ *,v
567                PMSTART
568                IF $(REF) ~ *
569                    SET $(isinif) 1
570                    PM if ($(member)) {
571                    INDENT +1
572                ENDIF
573                SET $(isloop) 1
574                PM for (int index = 0; index < $(SIZE:THIS->=$(self)$(deref)); index++) {
575                INDENT +1
576                SET $(member) $(member)[index]
577            ENDIF
578            IF $(TYPE) = dllh
579                PUSH
580                MOVETO $(/AISC/DATA/STRUCT.dll_header)
581                GOSUB delete_structure,$(member),.
582                POP
583            ELSEIF $(REF) ~ s
584                IF $(REF) ~ o,d,i
585                    PUSH
586                    IF $(REF) ~ i
587                        CREATE $(subderef) .
588                    ELSE
589                        P if ($(member)) {
590                        INDENT +1
591                        CREATE $(subderef) ->
592                    ENDIF
593                    MOVETO $(/AISC/DATA/STRUCT.$(TYPE))
594                    GOSUB delete_structure,$(member),$(subderef)
595                    POP
596                    IF $(REF) !~ i
597                        P free($(member));
598                        INDENT -1
599                        P }
600                    ENDIF
601                ENDIF
602            ELSEIF $(REF) ~ d,o
603                IF $(REF) ~ d
604                    P while $\
605                ELSE
606                    P if $\
607                ENDIF
608                P ($(member)) {
609                INDENT +1
610                    P destroy_$(TYPE)($(member));
611                    P if (aisc_server_error) return;
612                INDENT -1
613                P }
614            ELSEIF $(REF) ~ t,e
615                IF $(TYPE) = aisc_string
616                    P free($(member));
617                ELSEIF $(TYPE) = bytestring
618                    P free($(member).data);
619                ENDIF
620            ELSEIF $(REF) ~ l
621            ELSE
622                ERROR UNKNOWN REF '$(REF|)' in $(STRUCT).$(TYPE)
623            ENDIF
624
625            IF $(isloop) = 1
626                INDENT -1
627                PM }
628                IF $(isinif) = 1
629                    INDENT -1
630                    PM }
631                ENDIF
632                PMEND
633            ENDIF
634        ENDIF
635    ENDFOR
636RETURN
637
638FUNCTION build_delete
639    P // -----------
640    P // destructors
641    --
642   
643    FOR $(STRUCT)
644        IF $(extern_destroy_$(STRUCT))
645        ELSE
646            PUSH
647            CREATE $(islinked) = 0
648            CREATE $(ident)
649   
650            PUSH
651            MOVETO $({/.)
652            IF $(TYPE) = dllh
653                SET $(islinked) = 1
654                SET $(ident) = $(IDENT)
655            ENDIF
656            POP
657   
658            # pass pointers to not-linked objects by reference and set them to NULp below
659            # linked object-pointers are set to NULp by aisc_unlink
660            P void destroy_$(STRUCT)($(STRUCT)$\
661            IF $(islinked) = 1
662                P  *obj$\
663            ELSE
664                P *& obj$\
665            ENDIF
666            P ) {
667            INDENT +1
668                IF $(islinked) = 1
669                    P if (obj->$(ident).parent) {
670                    INDENT +1
671                        P aisc_unlink((dllheader_ext*)obj);
672                        P if (aisc_server_error) return;
673                    INDENT -1
674                    P }
675                ENDIF
676                GOSUB delete_structure,obj,->
677                IF $(islinked) = 1
678                    P free(obj);
679                ELSE
680                    P freenull(obj);
681                ENDIF
682                GOSUB trace "destroyed $(STRUCT)"
683            INDENT -1
684            P }
685            --
686            POP
687        ENDIF
688    ENDFOR
689RETURN
690
691FUNCTION move_structure
692    CREATE $(isloop)
693    CREATE $(my_key)
694    CREATE $(index)
695    CREATE $(access)
696
697    FOR $({/TYPE)
698        SET $(index)
699        SET $(access) $(IDENT)
700        SET $(isloop) 0
701        IF $(REF) ~ $(v)
702        ELSEIF $(IDENT) = key
703        ELSE
704            IF $(REF) ~ *,v
705                IF $(SIZE)
706                    SET $(index) $(SIZE:THIS->=sobj->)
707                ELSE
708                    ERROR Missing SIZE in STRUCT $(STRUCT) ident $(IDENT)
709                ENDIF
710                IF $(REF) ~ *
711                    P if (dobj->$(access))$\
712                ENDIF
713
714                SET $(isloop) 1
715                PMSTART
716                PM for (int index = 0; index < $(index); index++) {
717                INDENT +1
718                SET $(access) $(access)[index]
719            ENDIF
720            IF $(TYPE) = dllh
721                P move_dll_header(&(sobj->$(access)), &(dobj->$(access)));
722            ELSEIF $(REF) ~ l,r
723                P dobj->$(access) $|= sobj->$(access); $\
724                P $|trf_link((long)sobj->$(access), (long*)&dobj->$(access));
725            ELSEIF $(REF) ~ o
726                P dobj->$(access) $|= copy_$(TYPE)(sobj->$(access));
727            ELSEIF $(REF) ~ d
728                P for ($(TYPE) *cobj = sobj->$(access); cobj; cobj = cobj->next) {
729                INDENT +1
730                    P $(TYPE) *d2obj = copy_$(TYPE)(cobj);
731                    P if (!d2obj) return 1;
732                    P aisc_server_error = aisc_link((dllpublic_ext*)&(dobj->p$(access)), (dllheader_ext*)d2obj);
733                    P if (aisc_server_error) return 1;
734                INDENT -1
735                P }
736            ELSEIF $(REF) ~ s
737                IF $(REF) ~ i
738                    P if (move_$(TYPE)(&(sobj->$(access)), &(dobj->$(access)))) return 1;
739                ENDIF
740            ELSEIF $(REF) ~ t,e
741                IF $(TYPE) = aisc_string
742                    P dobj->$(access) $|= nulldup(sobj->$(access));
743                ELSEIF $(TYPE) = bytestring
744                    P if (sobj->$(access).data) {
745                    INDENT +1
746                        P dobj->$(access).data = (char *)malloc(sobj->$(access).size);
747                        P memcpy(dobj->$(access).data, sobj->$(access).data, sobj->$(access).size);
748                        P dobj->$(access).size = sobj->$(access).size;
749                    INDENT -1
750                    P }
751                ELSE
752                    P dobj->$(access) $|= sobj->$(access);
753                ENDIF
754            ELSE
755                PP UNKNOWN REF '$(REF|)' in $(STRUCT).$(TYPE)
756            ENDIF
757            IF $(isloop) = 1
758                INDENT -1
759                PM }
760                PMEND
761            ENDIF
762        ENDIF
763    ENDFOR
764RETURN
765
766FUNCTION build_move
767    P // ------------
768    P // move objects
769    --
770    FOR $(STRUCT)
771        IF $(extern_move_$(STRUCT))
772        ELSE
773            P static int move_$(STRUCT)(const $(STRUCT) *sobj, $(STRUCT) *dobj) {
774            INDENT +1
775                GOSUB move_structure
776                P return 0;
777            INDENT -1
778            P }
779            --
780        ENDIF
781    ENDFOR
782RETURN
783
784FUNCTION build_copy
785    P // ------------
786    P // copy objects
787    --
788    FOR $(STRUCT)
789        IF $(extern_copy_$(STRUCT))
790        ELSE
791            P $(STRUCT) *copy_$(STRUCT)(const $(STRUCT) *sobj) {
792            INDENT +1
793                P $(STRUCT) *dobj = NULp;
794                P if (sobj) {
795                INDENT +1
796                    P dobj = create_$(STRUCT)();
797                    P if (!dobj) alloc_err("$(STRUCT)");
798                    P else {
799                    INDENT +1
800                        P trf_create((long)sobj, (long)dobj);
801                        P if (move_$(STRUCT)(sobj, dobj)) {
802                        INDENT +1
803                            P destroy_$(STRUCT)(dobj);
804                            P dobj = NULp;
805                        INDENT -1
806                        P }
807                    INDENT -1
808                    P }
809                INDENT -1
810                P }
811                GOSUB trace "copied $(STRUCT)"
812                P return dobj;
813            INDENT -1
814            P }
815            --
816        ENDIF
817    ENDFOR
818RETURN
819
820FUNCTION save_structure self,deref,prekey,fp
821    CREATE $(member)
822    CREATE $(isloop)
823    CREATE $(isinif)
824    CREATE $(saved_elems) = 0
825
826    FOR $({/TYPE)
827        SET $(member) $(self)$(deref)$(IDENT)
828        SET $(isloop) 0
829        SET $(isinif) 0
830
831        IF $(REF) ~ $(v)
832            # virtual function
833        ELSEIF $(SAVE)
834            SET $(saved_elems) = $(+ $(saved_elems)+1)
835            IF $(REF) ~ *,v
836                PMSTART
837                IF $(REF) ~ *
838                    SET $(isinif) 1
839                    PM if ($(access)) {
840                    INDENT +1
841                ENDIF
842                SET $(isloop) 1
843                PM for (int index = 0; index < $(SIZE:THIS->=$(self)$(deref); index++) {
844                INDENT +1
845                SET $(member) $(member)[index]
846            ENDIF
847            IF $(TYPE) = dllh
848                PUSH
849                CREATE $(pk) $(prekey)$(KEY)
850                MOVETO $(/AISC/DATA/STRUCT.dll_header)
851                GOSUB save_structure,$(member),.,$(pk),$(fp)
852                POP
853            ELSEIF $(REF) ~ s
854                IF $(REF) ~ o,d,i
855                    ERROR previously unused - check generated code!
856                    PUSH
857                    IF $(REF) ~ i
858                        CREATE $(subderef) .
859                    ELSE
860                        PMSTART
861                        PM if ($(member)) {
862                        INDENT +1
863                        CREATE $(subderef) ->
864                    ENDIF
865                    CREATE $(pk) $(prekey)$(KEY|NOKEYDEFINED)
866                    MOVETO $(/AISC/DATA/STRUCT.$(TYPE))
867                    GOSUB save_structure,$(member),$(subderef),$(pk),$(fp)
868                    POP
869                    IF $(REF) !~ i
870                        INDENT -1
871                        PM }
872                        PMEND
873                    ENDIF
874                ENDIF
875            ELSEIF $(REF) ~ d
876                IF $(saveable_$(TYPE)) = 0
877                    ERROR Can't save $(TYPE) (has no saveable members)
878                ENDIF
879                P for ($(TYPE) *s = $(member); s; s = s->next) {
880                INDENT +1
881                    P fputs("$(prekey)$(KEY|NOKEYDEFINED){ ", $(fp));
882                    P save_$(TYPE)(s, $(fp));
883                    P fputs("}\n", $(fp));
884                INDENT -1
885                P }
886            ELSEIF $(REF) ~ o
887                ERROR previously unused - check generated code!
888                IF $(saveable_$(TYPE)) = 0
889                    ERROR Can't save $(TYPE) (has no saveable members)
890                ENDIF
891                P fputs("$(prekey)$(KEY) {\n", $(fp));
892                P save_$TYPE($(member), $(fp));
893                P fputs("}\n", $(fp));
894            ELSEIF $(REF) ~ t,e
895                IF $(TYPE) = aisc_string
896                    P if ($(member)) $|save_string("$(prekey)$(KEY|NOKEYDEFINED)", $(member), $(fp));
897                ELSEIF $(TYPE) = int,long,char
898                    P fprintf($(fp), "$(prekey)$(KEY|NOKEYDEFINED) %i\n", $(member));
899                ELSEIF $(TYPE) = float,double
900                    P fprintf($(fp), "$(prekey)$(KEY|NOKEYDEFINED) %f\n", $(member));
901                ELSE
902                    ERROR CANNOT SAVE TYPE '$(TYPE)'
903                ENDIF
904            ELSEIF $(REF) ~ l
905                P fprintf($(fp), "$(prekey)$(KEY|NOKEYDEFINED) %i", $(member));
906            ELSE
907                ERROR UNKNOWN REF '$(REF|)' in $(STRUCT).$(TYPE)
908            ENDIF
909            IF $(isloop) = 1
910                INDENT -1
911                PM }
912                IF $(isinif) = 1
913                    INDENT -1
914                    PM }
915                ENDIF
916                PMEND
917            ENDIF
918        ENDIF
919    ENDFOR
920    IF $(saved_elems) = 0
921        ERROR It makes no sense to save $(STRUCT), since it has no saveable data elements
922    ENDIF
923RETURN
924
925FUNCTION load_structure self,deref,prekey,fp
926    CREATE $(member)
927    CREATE $(isloop)
928    CREATE $(isinif)
929
930    FOR $({/TYPE)
931        SET $(member) $(self)$(deref)$(IDENT)
932        SET $(isloop) 0
933        SET $(isinif) 0
934
935        IF $(REF) ~ $(v)
936            # virtual function
937        ELSEIF $(SAVE)
938            IF $(REF) ~ *,v
939                PMSTART
940                IF $(REF) ~ *
941                    SET $(isinif) 1
942                    PM if ($(member)) {
943                    INDENT +1
944                ENDIF
945                SET $(isloop) 1
946                PM for (int index = 0; index < $(SIZE:THIS->=$(self)$(deref); index++) {
947                INDENT +1
948                SET $(member) $(member)[index]
949            ENDIF
950            IF $(TYPE) = dllh
951                PUSH
952                CREATE $(pk) $(prekey)$(KEY)
953                MOVETO $(/AISC/DATA/STRUCT.dll_header)
954                GOSUB load_structure,$(member),.,$(pk),$(fp)
955                POP
956            ELSEIF $(REF) ~ s
957                IF $(REF) ~ o,d,i
958                    ERROR previously unused - check generated code!
959                    PUSH
960                    IF $(REF) ~ i
961                        CREATE $(subderef) .
962                    ELSE
963                        PMSTART
964                        PM if ($(member)) {
965                        INDENT +1
966                        CREATE $(subderef) ->
967                    ENDIF
968                    CREATE $(pk) $(prekey)$(KEY|NOKEYDEFINED)
969                    MOVETO $(/AISC/DATA/STRUCT.$(TYPE))
970                    GOSUB load_structure,$(member),$(subderef),$(pk),$(fp)
971                    POP
972                    IF $(REF) !~ i
973                        INDENT -1
974                        PM }
975                        PMEND
976                    ENDIF
977                ENDIF
978            ELSEIF $(REF) ~ d
979                P if (strcmp("$(prekey)$(KEY|NOKEYDEFINED){", token)==0) {
980                INDENT +1
981                    P $(TYPE) *cobj = create_$(TYPE)();
982                    P if (cobj) {
983                    INDENT +1
984                        P if (load_$(TYPE)(cobj, $(fp))==0) { 
985                        INDENT +1
986                            P aisc_link((dllpublic_ext*)&($(self)$(deref)p$(IDENT)), (dllheader_ext*)cobj);
987                            P continue;
988                        INDENT -1
989                        P }
990                        P destroy_$(TYPE)(cobj);
991                    INDENT -1
992                    P }
993                    P return 1;
994                INDENT -1
995                P }
996            ELSEIF $(REF) ~ o
997                ERROR code generated here is broken (does save instead of load)
998                P fprintf($(fp),"$(prekey)$(KEY) {\n");
999                P { int error = save_$TYPE($(member),$(fp));
1000                P if (error) return error; }
1001                P fprintf($(fp),"}\n");
1002            ELSEIF $(REF) ~ t,e
1003                P if (strcmp("$(prekey)$(KEY|NOKEYDEFINED)", token)==0) {
1004                INDENT +1
1005                    P if (aisc_server_load_token($(fp), token, $(TOKENSIZE))) return 1;
1006                    IF $(TYPE) = aisc_string
1007                        P $(member) = strdup(token);
1008                    ELSEIF $(TYPE) = int,long,char
1009                        P $(member) = atoi(token);
1010                    ELSEIF $(TYPE) = float,double
1011                        P $(member) = atof(token);
1012                    ELSE
1013                        ERROR Loading type '$(TYPE)' not implemented (yet)
1014                    ENDIF
1015                    P continue;
1016                INDENT -1
1017                P }
1018            ELSEIF $(REF) ~ l
1019                ERROR loading links not implemented (yet)
1020            ELSE
1021                ERROR UNKNOWN REF '$(REF|)' in $(STRUCT).$(TYPE)
1022            ENDIF
1023            IF $(isloop) = 1
1024                INDENT -1
1025                PM }
1026                IF $(isinif) = 1
1027                    INDENT -1
1028                    PM }
1029                ENDIF
1030                PMEND
1031            ENDIF
1032        ENDIF
1033    ENDFOR
1034RETURN
1035
1036FUNCTION build_saveload
1037    CREATE $(TOKENSIZE) 1024
1038
1039    P // -------------
1040    P // save and load
1041    --
1042    P inline void warn_unknown_token(const char *token, const char *objectname) {
1043    P $1fprintf(stderr, "Unknown token '%s' while loading '%s' (ignored)\n", token, objectname);
1044    P }
1045    --
1046    P inline void save_string(const char *key, const char *value, FILE *out) {
1047    INDENT +1
1048        P fputs(key, out);
1049        P fputc(' ', out);
1050        P aisc_server_save_token(out, value, $(TOKENSIZE));
1051    INDENT -1
1052    P }
1053    --
1054
1055    FOR $(STRUCT)
1056        CREATE $(saveable_$(STRUCT)) = 0
1057        FOR $({/TYPE)
1058            IF $(SAVE)
1059                SET $(saveable_$(STRUCT)) = 1
1060            ENDIF
1061        ENDFOR
1062        #WARNING saveable_$(STRUCT) = $(saveable_$(STRUCT))
1063    ENDFOR
1064
1065    FOR $(STRUCT)
1066        IF $(saveable_$(STRUCT)) = 1
1067            IF $(extern_save_$(STRUCT))
1068            ELSE
1069                P void save_$(STRUCT)(const $(STRUCT) *o, FILE *out) {
1070                INDENT +1
1071                    GOSUB save_structure,o,->,,out
1072                INDENT -1
1073                P }
1074                --
1075            ENDIF
1076        ENDIF
1077    ENDFOR
1078    FOR $(STRUCT)
1079        IF $(saveable_$(STRUCT)) = 1
1080            IF $(extern_load_$(STRUCT))
1081            ELSE
1082                P int load_$(STRUCT)($(STRUCT) *o, FILE *in) {
1083                INDENT +1
1084                    P char token[$(TOKENSIZE)+1];
1085                    P while (aisc_server_load_token(in, token, $(TOKENSIZE))==0) {
1086                    INDENT +1
1087                        P if (*token == '}') break;
1088                        GOSUB load_structure,o,->,,in
1089                        P warn_unknown_token(token, "$(STRUCT)");
1090                    INDENT -1
1091                    P }
1092                    P return 0;
1093                INDENT -1
1094                P }
1095                --
1096            ENDIF
1097        ENDIF
1098    ENDFOR
1099RETURN
1100
1101FUNCTION trace msg
1102    IF $(TRACE) = 1
1103        P fputs("AISC_SERVER_TRACE " $(msg) "\n", stderr); fflush(stderr);
1104    ENDIF
1105RETURN
1106
1107FUNCTION file_header
1108    P // -----------------------------------------------------------------
1109    P // Created automagically from ../$(argv[2])
1110    P //                        and ../$(argv[4])
1111    P // using aisc-script '../AISC/aisc_server.pa'
1112    P // DO NOT EDIT THIS FILE!!!
1113    P // -----------------------------------------------------------------
1114    --
1115RETURN
1116
1117# --------------------------------------------------------------------------------
1118
1119LABEL main
1120IF $(argc) < 7
1121    ERROR Wrong number of parameters[$(argc)]. Usage: aisc aisc_server.pa xxx.aisc outfile externfile.aisc import_proto globals.aisc
1122ENDIF
1123
1124DATA AISC { $(#FILE $(argv[2])) }, EXTERN { $(#FILE $(argv[4])) }, GLOBALS { $(#FILE $(argv[6])) };
1125DUMPDATA DUMP/aisc_server.pa__$(argv[2]).dump
1126
1127OPEN save $(argv[3])
1128OPEN import $(argv[5])
1129
1130# set extern functions
1131MOVETO $(EXTERN/.)
1132FOR $(FUNCTION)
1133    CREATE $(extern_$(FUNCTION))
1134NEXT
1135    ERROR no extern Functions found
1136ENDFOR
1137
1138# set globals passed from Makefile
1139MOVETO $(/GLOBALS/.)
1140CREATE $(create_save_code) = $(AISC_SAVE)
1141
1142OUT import
1143CALL file_header
1144
1145OUT save
1146CALL file_header
1147P $(#FILE C/aisc_server.h)
1148
1149MOVETO $(/AISC/DATA/.)
1150
1151CREATE $(v) = %
1152
1153CALL build_init
1154CALL build_delete
1155CALL build_move
1156CALL build_copy
1157CALL build_accessors
1158
1159IF $(create_save_code) = YES
1160    CALL build_saveload
1161ENDIF
1162
1163
1164CLOSE save
1165CLOSE import
1166EXIT
1167
Note: See TracBrowser for help on using the repository browser.