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

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