-
Notifications
You must be signed in to change notification settings - Fork 4
/
auto_xlsxwriter.bi
2330 lines (2158 loc) · 103 KB
/
auto_xlsxwriter.bi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#pragma once
#include once "crt/stdint.bi"
#include once "crt/stdio.bi"
#include once "crt/errno.bi"
#include once "crt/stdlib.bi"
#include once "crt/string.bi"
#include once "crt/time.bi"
extern "C"
#define NULL 0
#define __LXW_XLSXWRITER_H__
#define __LXW_WORKBOOK_H__
#define __LXW_WORKSHEET_H__
#define __LXW_SST_H__
#define __LXW_COMMON_H__
#define _SYS_QUEUE_H_
#define QMD_TRACE_ELEM(elem)
#define QMD_TRACE_HEAD(head)
#define QMD_SAVELINK(name, link)
#define TRACEBUF
#define TRACEBUF_INITIALIZER
#define TRASHIT(x)
'' TODO: #define SLIST_HEAD(name, type) struct name { struct type *slh_first; }
#define SLIST_HEAD_INITIALIZER(head) (NULL)
'' TODO: #define SLIST_ENTRY(type) struct { struct type *sle_next; }
#define SLIST_EMPTY(head) ((head)->slh_first = NULL)
#define SLIST_FIRST(head) (head)->slh_first
'' TODO: #define SLIST_FOREACH(var, head, field) for ((var) = SLIST_FIRST((head)); (var); (var) = SLIST_NEXT((var), field))
'' TODO: #define SLIST_FOREACH_FROM(var, head, field) for ((var) = ((var) ? (var) : SLIST_FIRST((head))); (var); (var) = SLIST_NEXT((var), field))
'' TODO: #define SLIST_FOREACH_SAFE(var, head, field, tvar) for ((var) = SLIST_FIRST((head)); (var) && ((tvar) = SLIST_NEXT((var), field), 1); (var) = (tvar))
'' TODO: #define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) for ((var) = ((var) ? (var) : SLIST_FIRST((head))); (var) && ((tvar) = SLIST_NEXT((var), field), 1); (var) = (tvar))
'' TODO: #define SLIST_FOREACH_PREVPTR(var, varp, head, field) for ((varp) = &SLIST_FIRST((head)); ((var) = *(varp)) != NULL; (varp) = &SLIST_NEXT((var), field))
#define SLIST_INIT(head) scope : SLIST_FIRST((head)) = NULL : end scope
#macro SLIST_INSERT_AFTER(slistelm, elm, field)
scope
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field)
SLIST_NEXT((slistelm), field) = (elm)
end scope
#endmacro
#macro SLIST_INSERT_HEAD(head, elm, field)
scope
SLIST_NEXT((elm), field) = SLIST_FIRST((head))
SLIST_FIRST((head)) = (elm)
end scope
#endmacro
#define SLIST_NEXT(elm, field) (elm)->field.sle_next
#macro SLIST_REMOVE(head, elm, type, field)
scope
QMD_SAVELINK(oldnext, (elm)->field.sle_next)
if SLIST_FIRST((head)) = (elm) then
SLIST_REMOVE_HEAD((head), field)
else
dim curelm as type ptr = SLIST_FIRST((head))
while SLIST_NEXT(curelm, field) <> (elm)
curelm = SLIST_NEXT(curelm, field)
wend
SLIST_REMOVE_AFTER(curelm, field)
end if
TRASHIT(*oldnext)
end scope
#endmacro
#define SLIST_REMOVE_AFTER(elm, field) scope : SLIST_NEXT(elm, field) = SLIST_NEXT(SLIST_NEXT(elm, field), field) : end scope
#define SLIST_REMOVE_HEAD(head, field) scope : SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field) : end scope
#macro SLIST_SWAP(head1, head2, type)
scope
dim swap_first as type ptr = SLIST_FIRST(head1)
SLIST_FIRST(head1) = SLIST_FIRST(head2)
SLIST_FIRST(head2) = swap_first
end scope
#endmacro
#define STAILQ_HEAD(name, type) struct name { struct type *stqh_first; struct type **stqh_last; }
#define STAILQ_HEAD_INITIALIZER(head) (NULL, @(head).stqh_first)
#define STAILQ_ENTRY(type) struct { struct type *stqe_next; }
#macro STAILQ_CONCAT(head1, head2)
if STAILQ_EMPTY((head2)) = 0 then
(*(head1)->stqh_last) = (head2)->stqh_first
(head1)->stqh_last = (head2)->stqh_last
STAILQ_INIT((head2))
end if
#endmacro
#define STAILQ_EMPTY(head) ((head)->stqh_first = NULL)
#define STAILQ_FIRST(head) (head)->stqh_first
#define STAILQ_FOREACH(var, head, field) for((var) = STAILQ_FIRST((head)); (var); (var) = STAILQ_NEXT((var), field))
#define STAILQ_FOREACH_FROM(var, head, field) for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); (var); (var) = STAILQ_NEXT((var), field))
#define STAILQ_FOREACH_SAFE(var, head, field, tvar) for ((var) = STAILQ_FIRST((head)); (var) && ((tvar) = STAILQ_NEXT((var), field), 1); (var) = (tvar))
#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); (var) && ((tvar) = STAILQ_NEXT((var), field), 1); (var) = (tvar))
#macro STAILQ_INIT(head)
scope
STAILQ_FIRST((head)) = NULL
(head)->stqh_last = @STAILQ_FIRST((head))
end scope
#endmacro
#macro STAILQ_INSERT_AFTER(head, tqelm, elm, field)
scope
'' TODO: if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL) (head)->stqh_last = &STAILQ_NEXT((elm), field);
STAILQ_NEXT((tqelm), field) = (elm)
end scope
#endmacro
#macro STAILQ_INSERT_HEAD(head, elm, field)
scope
'' TODO: if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) (head)->stqh_last = &STAILQ_NEXT((elm), field);
STAILQ_FIRST((head)) = (elm)
end scope
#endmacro
#macro STAILQ_INSERT_TAIL(head, elm, field)
scope
STAILQ_NEXT((elm), field) = NULL
(*(head)->stqh_last) = (elm)
(head)->stqh_last = @STAILQ_NEXT((elm), field)
end scope
#endmacro
'' TODO: #define STAILQ_LAST(head, type, field) (STAILQ_EMPTY((head)) ? NULL : __containerof((head)->stqh_last, struct type, field.stqe_next))
#define STAILQ_NEXT(elm, field) (elm)->field.stqe_next
#macro STAILQ_REMOVE(head, elm, type, field)
scope
QMD_SAVELINK(oldnext, (elm)->field.stqe_next)
if STAILQ_FIRST((head)) = (elm) then
STAILQ_REMOVE_HEAD((head), field)
else
dim curelm as type ptr = STAILQ_FIRST((head))
while STAILQ_NEXT(curelm, field) <> (elm)
curelm = STAILQ_NEXT(curelm, field)
wend
STAILQ_REMOVE_AFTER(head, curelm, field)
end if
TRASHIT(*oldnext)
end scope
#endmacro
#define STAILQ_REMOVE_AFTER(head, elm, field) scope : /' TODO: if ((STAILQ_NEXT(elm, field) = STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) (head)->stqh_last = &STAILQ_NEXT((elm), field); '/ : end scope
#define STAILQ_REMOVE_HEAD(head, field) scope : /' TODO: if ((STAILQ_FIRST((head)) = STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) (head)->stqh_last = &STAILQ_FIRST((head)); '/ : end scope
#macro STAILQ_SWAP(head1, head2, type)
scope
dim swap_first as type ptr = STAILQ_FIRST(head1)
dim swap_last as type ptr ptr = (head1)->stqh_last
STAILQ_FIRST(head1) = STAILQ_FIRST(head2)
(head1)->stqh_last = (head2)->stqh_last
STAILQ_FIRST(head2) = swap_first
(head2)->stqh_last = swap_last
if STAILQ_EMPTY(head1) then
(head1)->stqh_last = @STAILQ_FIRST(head1)
end if
if STAILQ_EMPTY(head2) then
(head2)->stqh_last = @STAILQ_FIRST(head2)
end if
end scope
#endmacro
'' TODO: #define LIST_HEAD(name, type) struct name { struct type *lh_first; }
#define LIST_HEAD_INITIALIZER(head) (NULL)
'' TODO: #define LIST_ENTRY(type) struct { struct type *le_next; struct type **le_prev; }
#define QMD_LIST_CHECK_HEAD(head, field)
#define QMD_LIST_CHECK_NEXT(elm, field)
#define QMD_LIST_CHECK_PREV(elm, field)
#define LIST_EMPTY(head) ((head)->lh_first = NULL)
#define LIST_FIRST(head) (head)->lh_first
'' TODO: #define LIST_FOREACH(var, head, field) for ((var) = LIST_FIRST((head)); (var); (var) = LIST_NEXT((var), field))
'' TODO: #define LIST_FOREACH_FROM(var, head, field) for ((var) = ((var) ? (var) : LIST_FIRST((head))); (var); (var) = LIST_NEXT((var), field))
'' TODO: #define LIST_FOREACH_SAFE(var, head, field, tvar) for ((var) = LIST_FIRST((head)); (var) && ((tvar) = LIST_NEXT((var), field), 1); (var) = (tvar))
'' TODO: #define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) for ((var) = ((var) ? (var) : LIST_FIRST((head))); (var) && ((tvar) = LIST_NEXT((var), field), 1); (var) = (tvar))
#define LIST_INIT(head) scope : LIST_FIRST((head)) = NULL : end scope
#macro LIST_INSERT_AFTER(listelm, elm, field)
scope
QMD_LIST_CHECK_NEXT(listelm, field)
'' TODO: if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) LIST_NEXT((listelm), field)->field.le_prev = &LIST_NEXT((elm), field);
LIST_NEXT((listelm), field) = (elm)
(elm)->field.le_prev = @LIST_NEXT((listelm), field)
end scope
#endmacro
#macro LIST_INSERT_BEFORE(listelm, elm, field)
scope
QMD_LIST_CHECK_PREV(listelm, field)
(elm)->field.le_prev = (listelm)->field.le_prev
LIST_NEXT((elm), field) = (listelm)
(*(listelm)->field.le_prev) = (elm)
(listelm)->field.le_prev = @LIST_NEXT((elm), field)
end scope
#endmacro
#macro LIST_INSERT_HEAD(head, elm, field)
scope
QMD_LIST_CHECK_HEAD((head), field)
'' TODO: if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);
LIST_FIRST((head)) = (elm)
(elm)->field.le_prev = @LIST_FIRST((head))
end scope
#endmacro
#define LIST_NEXT(elm, field) (elm)->field.le_next
'' TODO: #define LIST_PREV(elm, head, type, field) ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : __containerof((elm)->field.le_prev, struct type, field.le_next))
#macro LIST_REMOVE(elm, field)
scope
QMD_SAVELINK(oldnext, (elm)->field.le_next)
QMD_SAVELINK(oldprev, (elm)->field.le_prev)
QMD_LIST_CHECK_NEXT(elm, field)
QMD_LIST_CHECK_PREV(elm, field)
if LIST_NEXT((elm), field) <> NULL then
LIST_NEXT((elm), field)->field.le_prev = (elm)->field.le_prev
end if
(*(elm)->field.le_prev) = LIST_NEXT((elm), field)
TRASHIT(*oldnext)
TRASHIT(*oldprev)
end scope
#endmacro
#macro LIST_SWAP(head1, head2, type, field)
scope
dim swap_tmp as type ptr = LIST_FIRST((head1))
LIST_FIRST((head1)) = LIST_FIRST((head2))
LIST_FIRST((head2)) = swap_tmp
'' TODO: if ((swap_tmp = LIST_FIRST((head1))) != NULL) swap_tmp->field.le_prev = &LIST_FIRST((head1));
'' TODO: if ((swap_tmp = LIST_FIRST((head2))) != NULL) swap_tmp->field.le_prev = &LIST_FIRST((head2));
end scope
#endmacro
'' TODO: #define TAILQ_HEAD(name, type) struct name { struct type *tqh_first; struct type **tqh_last; TRACEBUF }
#define TAILQ_HEAD_INITIALIZER(head) (NULL, @(head).tqh_first, TRACEBUF_INITIALIZER)
'' TODO: #define TAILQ_ENTRY(type) struct { struct type *tqe_next; struct type **tqe_prev; TRACEBUF }
#define QMD_TAILQ_CHECK_HEAD(head, field)
#define QMD_TAILQ_CHECK_TAIL(head, headname)
#define QMD_TAILQ_CHECK_NEXT(elm, field)
#define QMD_TAILQ_CHECK_PREV(elm, field)
#macro TAILQ_CONCAT(head1, head2, field)
if TAILQ_EMPTY(head2) = 0 then
(*(head1)->tqh_last) = (head2)->tqh_first
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last
(head1)->tqh_last = (head2)->tqh_last
TAILQ_INIT((head2))
QMD_TRACE_HEAD(head1)
QMD_TRACE_HEAD(head2)
end if
#endmacro
#define TAILQ_EMPTY(head) ((head)->tqh_first = NULL)
#define TAILQ_FIRST(head) (head)->tqh_first
'' TODO: #define TAILQ_FOREACH(var, head, field) for ((var) = TAILQ_FIRST((head)); (var); (var) = TAILQ_NEXT((var), field))
'' TODO: #define TAILQ_FOREACH_FROM(var, head, field) for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); (var); (var) = TAILQ_NEXT((var), field))
'' TODO: #define TAILQ_FOREACH_SAFE(var, head, field, tvar) for ((var) = TAILQ_FIRST((head)); (var) && ((tvar) = TAILQ_NEXT((var), field), 1); (var) = (tvar))
'' TODO: #define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); (var) && ((tvar) = TAILQ_NEXT((var), field), 1); (var) = (tvar))
'' TODO: #define TAILQ_FOREACH_REVERSE(var, head, headname, field) for ((var) = TAILQ_LAST((head), headname); (var); (var) = TAILQ_PREV((var), headname, field))
'' TODO: #define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); (var); (var) = TAILQ_PREV((var), headname, field))
'' TODO: #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) for ((var) = TAILQ_LAST((head), headname); (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); (var) = (tvar))
'' TODO: #define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); (var) = (tvar))
#macro TAILQ_INIT(head)
scope
TAILQ_FIRST((head)) = NULL
(head)->tqh_last = @TAILQ_FIRST((head))
QMD_TRACE_HEAD(head)
end scope
#endmacro
#macro TAILQ_INSERT_AFTER(head, listelm, elm, field)
scope
QMD_TAILQ_CHECK_NEXT(listelm, field)
'' TODO: if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL) TAILQ_NEXT((elm), field)->field.tqe_prev = &TAILQ_NEXT((elm), field);
'' TODO: else { (head)->tqh_last = &TAILQ_NEXT((elm), field); QMD_TRACE_HEAD(head); } TAILQ_NEXT((listelm), field) = (elm);
(elm)->field.tqe_prev = @TAILQ_NEXT((listelm), field)
QMD_TRACE_ELEM(@(elm)->field)
QMD_TRACE_ELEM(@listelm->field)
end scope
#endmacro
#macro TAILQ_INSERT_BEFORE(listelm, elm, field)
scope
QMD_TAILQ_CHECK_PREV(listelm, field)
(elm)->field.tqe_prev = (listelm)->field.tqe_prev
TAILQ_NEXT((elm), field) = (listelm)
(*(listelm)->field.tqe_prev) = (elm)
(listelm)->field.tqe_prev = @TAILQ_NEXT((elm), field)
QMD_TRACE_ELEM(@(elm)->field)
QMD_TRACE_ELEM(@listelm->field)
end scope
#endmacro
#macro TAILQ_INSERT_HEAD(head, elm, field)
scope
QMD_TAILQ_CHECK_HEAD(head, field)
'' TODO: if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) TAILQ_FIRST((head))->field.tqe_prev = &TAILQ_NEXT((elm), field);
'' TODO: else (head)->tqh_last = &TAILQ_NEXT((elm), field);
TAILQ_FIRST((head)) = (elm)
(elm)->field.tqe_prev = @TAILQ_FIRST((head))
QMD_TRACE_HEAD(head)
QMD_TRACE_ELEM(@(elm)->field)
end scope
#endmacro
#macro TAILQ_INSERT_TAIL(head, elm, field)
scope
QMD_TAILQ_CHECK_TAIL(head, field)
TAILQ_NEXT((elm), field) = NULL
(elm)->field.tqe_prev = (head)->tqh_last
(*(head)->tqh_last) = (elm)
(head)->tqh_last = @TAILQ_NEXT((elm), field)
QMD_TRACE_HEAD(head)
QMD_TRACE_ELEM(@(elm)->field)
end scope
#endmacro
#define TAILQ_LAST(head, headname) (*cptr(headname ptr, (head)->tqh_last)->tqh_last)
#define TAILQ_NEXT(elm, field) (elm)->field.tqe_next
#define TAILQ_PREV(elm, headname, field) (*cptr(headname ptr, (elm)->field.tqe_prev)->tqh_last)
#macro TAILQ_REMOVE(head, elm, field)
scope
QMD_SAVELINK(oldnext, (elm)->field.tqe_next)
QMD_SAVELINK(oldprev, (elm)->field.tqe_prev)
QMD_TAILQ_CHECK_NEXT(elm, field)
QMD_TAILQ_CHECK_PREV(elm, field)
if TAILQ_NEXT((elm), field) <> NULL then
TAILQ_NEXT((elm), field)->field.tqe_prev = (elm)->field.tqe_prev
else
(head)->tqh_last = (elm)->field.tqe_prev
QMD_TRACE_HEAD(head)
end if
(*(elm)->field.tqe_prev) = TAILQ_NEXT((elm), field)
TRASHIT(*oldnext)
TRASHIT(*oldprev)
QMD_TRACE_ELEM(@(elm)->field)
end scope
#endmacro
#macro TAILQ_SWAP(head1, head2, type, field)
scope
dim swap_first as type ptr = (head1)->tqh_first
dim swap_last as type ptr ptr = (head1)->tqh_last
(head1)->tqh_first = (head2)->tqh_first
(head1)->tqh_last = (head2)->tqh_last
(head2)->tqh_first = swap_first
(head2)->tqh_last = swap_last
'' TODO: if ((swap_first = (head1)->tqh_first) != NULL) swap_first->field.tqe_prev = &(head1)->tqh_first;
'' TODO: else (head1)->tqh_last = &(head1)->tqh_first;
'' TODO: if ((swap_first = (head2)->tqh_first) != NULL) swap_first->field.tqe_prev = &(head2)->tqh_first;
'' TODO: else (head2)->tqh_last = &(head2)->tqh_first;
end scope
#endmacro
#define _SYS_TREE_H_
'' TODO: #define SPLAY_HEAD(name, type) struct name { struct type *sph_root; }
#define SPLAY_INITIALIZER(root) (NULL)
#define SPLAY_INIT(root) scope : (root)->sph_root = NULL : end scope
'' TODO: #define SPLAY_ENTRY(type) struct { struct type *spe_left; struct type *spe_right; }
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
#define SPLAY_ROOT(head) (head)->sph_root
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) = NULL)
#macro SPLAY_ROTATE_RIGHT(head, tmp, field)
scope
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field)
SPLAY_RIGHT(tmp, field) = (head)->sph_root
(head)->sph_root = tmp
end scope
#endmacro
#macro SPLAY_ROTATE_LEFT(head, tmp, field)
scope
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field)
SPLAY_LEFT(tmp, field) = (head)->sph_root
(head)->sph_root = tmp
end scope
#endmacro
#macro SPLAY_LINKLEFT(head, tmp, field)
scope
SPLAY_LEFT(tmp, field) = (head)->sph_root
tmp = (head)->sph_root
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field)
end scope
#endmacro
#macro SPLAY_LINKRIGHT(head, tmp, field)
scope
SPLAY_RIGHT(tmp, field) = (head)->sph_root
tmp = (head)->sph_root
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field)
end scope
#endmacro
#macro SPLAY_ASSEMBLE(head, node, left, right, field)
scope
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field)
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field)
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field)
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field)
end scope
#endmacro
'' TODO: #define SPLAY_PROTOTYPE(name, type, field, cmp) void name##_SPLAY(struct name *, struct type *); void name##_SPLAY_MINMAX(struct name *, int); struct type *name##_SPLAY_INSERT(struct name *, struct type *); struct type *name##_SPLAY_REMOVE(struct name *, struct type *); static __inline struct type * name##_SPLAY_FIND(struct name *head, struct type *elm) { if (SPLAY_EMPTY(head)) return(NULL); name##_SPLAY(head, elm); if ((cmp)(elm, (head)->sph_root) == 0) return (head->sph_root); return (NULL); } static __inline struct type * name##_SPLAY_NEXT(struct name *head, struct type *elm) { name##_SPLAY(head, elm); if (SPLAY_RIGHT(elm, field) != NULL) { elm = SPLAY_RIGHT(elm, field); while (SPLAY_LEFT(elm, field) != NULL) { elm = SPLAY_LEFT(elm, field); } } else elm = NULL; return (elm); } static __inline struct type * name##_SPLAY_MIN_MAX(struct name *head, int val) { name##_SPLAY_MINMAX(head, val); return (SPLAY_ROOT(head)); }
'' TODO: #define SPLAY_GENERATE(name, type, field, cmp) struct type * name##_SPLAY_INSERT(struct name *head, struct type *elm) { if (SPLAY_EMPTY(head)) { SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; } else { int __comp; name##_SPLAY(head, elm); __comp = (cmp)(elm, (head)->sph_root); if(__comp < 0) { SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); SPLAY_RIGHT(elm, field) = (head)->sph_root; SPLAY_LEFT((head)->sph_root, field) = NULL; } else if (__comp > 0) { SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); SPLAY_LEFT(elm, field) = (head)->sph_root; SPLAY_RIGHT((head)->sph_root, field) = NULL; } else return ((head)->sph_root); } (head)->sph_root = (elm); return (NULL); } struct type * name##_SPLAY_REMOVE(struct name *head, struct type *elm) { struct type *__tmp; if (SPLAY_EMPTY(head)) return (NULL); name##_SPLAY(head, elm); if ((cmp)(elm, (head)->sph_root) == 0) { if (SPLAY_LEFT((head)->sph_root, field) == NULL) { (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); } else { __tmp = SPLAY_RIGHT((head)->sph_root, field); (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); name##_SPLAY(head, elm); SPLAY_RIGHT((head)->sph_root, field) = __tmp; } return (elm); } return (NULL); } void name##_SPLAY(struct name *head, struct type *elm) { struct type __node, *__left, *__right, *__tmp; int __comp; SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; __left = __right = &__node; while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { if (__comp < 0) { __tmp = SPLAY_LEFT((head)->sph_root, field); if (__tmp == NULL) break; if ((cmp)(elm, __tmp) < 0){ SPLAY_ROTATE_RIGHT(head, __tmp, field); if (SPLAY_LEFT((head)->sph_root, field) == NULL) break; } SPLAY_LINKLEFT(head, __right, field); } else if (__comp > 0) { __tmp = SPLAY_RIGHT((head)->sph_root, field); if (__tmp == NULL) break; if ((cmp)(elm, __tmp) > 0){ SPLAY_ROTATE_LEFT(head, __tmp, field); if (SPLAY_RIGHT((head)->sph_root, field) == NULL) break; } SPLAY_LINKRIGHT(head, __left, field); } } SPLAY_ASSEMBLE(head, &__node, __left, __right, field); } void name##_SPLAY_MINMAX(struct name *head, int __comp) { struct type __node, *__left, *__right, *__tmp; SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; __left = __right = &__node; while (1) { if (__comp < 0) { __tmp = SPLAY_LEFT((head)->sph_root, field); if (__tmp == NULL) break; if (__comp < 0){ SPLAY_ROTATE_RIGHT(head, __tmp, field); if (SPLAY_LEFT((head)->sph_root, field) == NULL) break; } SPLAY_LINKLEFT(head, __right, field); } else if (__comp > 0) { __tmp = SPLAY_RIGHT((head)->sph_root, field); if (__tmp == NULL) break; if (__comp > 0) { SPLAY_ROTATE_LEFT(head, __tmp, field); if (SPLAY_RIGHT((head)->sph_root, field) == NULL) break; } SPLAY_LINKRIGHT(head, __left, field); } } SPLAY_ASSEMBLE(head, &__node, __left, __right, field); }
const SPLAY_NEGINF = -1
const SPLAY_INF = 1
'' TODO: #define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
'' TODO: #define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
'' TODO: #define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
'' TODO: #define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
'' TODO: #define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
'' TODO: #define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
'' TODO: #define SPLAY_FOREACH(x, name, head) for ((x) = SPLAY_MIN(name, head); (x) != NULL; (x) = SPLAY_NEXT(name, head, x))
'' TODO: #define RB_HEAD(name, type) struct name { struct type *rbh_root; }
#define RB_INITIALIZER(root) (NULL)
#define RB_INIT(root) scope : (root)->rbh_root = NULL : end scope
const RB_BLACK = 0
const RB_RED = 1
'' TODO: #define RB_ENTRY(type) struct { struct type *rbe_left; struct type *rbe_right; struct type *rbe_parent; int rbe_color; }
#define RB_LEFT(elm, field) (elm)->field.rbe_left
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
#define RB_COLOR(elm, field) (elm)->field.rbe_color
#define RB_ROOT(head) (head)->rbh_root
#define RB_EMPTY(head) (RB_ROOT(head) = NULL)
#macro RB_SET(elm, parent, field)
scope
RB_PARENT(elm, field) = parent
'' TODO: RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;
RB_COLOR(elm, field) = RB_RED
end scope
#endmacro
#macro RB_SET_BLACKRED(black, red, field)
scope
RB_COLOR(black, field) = RB_BLACK
RB_COLOR(red, field) = RB_RED
end scope
#endmacro
#macro RB_AUGMENT(x)
scope
end scope
#endmacro
#macro RB_ROTATE_LEFT(head, elm, tmp, field)
scope
(tmp) = RB_RIGHT(elm, field)
'' TODO: if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { RB_PARENT(RB_LEFT(tmp, field), field) = (elm); }
RB_AUGMENT(elm)
'' TODO: if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) RB_LEFT(RB_PARENT(elm, field), field) = (tmp); else RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); }
'' TODO: else (head)->rbh_root = (tmp);
RB_LEFT(tmp, field) = (elm)
RB_PARENT(elm, field) = (tmp)
RB_AUGMENT(tmp)
if RB_PARENT(tmp, field) then
RB_AUGMENT(RB_PARENT(tmp, field))
end if
end scope
#endmacro
#macro RB_ROTATE_RIGHT(head, elm, tmp, field)
scope
(tmp) = RB_LEFT(elm, field)
'' TODO: if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); }
RB_AUGMENT(elm)
'' TODO: if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) RB_LEFT(RB_PARENT(elm, field), field) = (tmp); else RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); }
'' TODO: else (head)->rbh_root = (tmp);
RB_RIGHT(tmp, field) = (elm)
RB_PARENT(elm, field) = (tmp)
RB_AUGMENT(tmp)
if RB_PARENT(tmp, field) then
RB_AUGMENT(RB_PARENT(tmp, field))
end if
end scope
#endmacro
'' TODO: #define RB_PROTOTYPE(name, type, field, cmp) RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
'' TODO: #define RB_PROTOTYPE_STATIC(name, type, field, cmp) RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
'' TODO: #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) RB_PROTOTYPE_INSERT_COLOR(name, type, attr); RB_PROTOTYPE_REMOVE_COLOR(name, type, attr); RB_PROTOTYPE_INSERT(name, type, attr); RB_PROTOTYPE_REMOVE(name, type, attr); RB_PROTOTYPE_FIND(name, type, attr); RB_PROTOTYPE_NFIND(name, type, attr); RB_PROTOTYPE_NEXT(name, type, attr); RB_PROTOTYPE_PREV(name, type, attr); RB_PROTOTYPE_MINMAX(name, type, attr);
'' TODO: #define RB_PROTOTYPE_INSERT_COLOR(name, type, attr) attr void name##_RB_INSERT_COLOR(struct name *, struct type *)
'' TODO: #define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr) attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *)
'' TODO: #define RB_PROTOTYPE_REMOVE(name, type, attr) attr struct type *name##_RB_REMOVE(struct name *, struct type *)
'' TODO: #define RB_PROTOTYPE_INSERT(name, type, attr) attr struct type *name##_RB_INSERT(struct name *, struct type *)
'' TODO: #define RB_PROTOTYPE_FIND(name, type, attr) attr struct type *name##_RB_FIND(struct name *, struct type *)
'' TODO: #define RB_PROTOTYPE_NFIND(name, type, attr) attr struct type *name##_RB_NFIND(struct name *, struct type *)
'' TODO: #define RB_PROTOTYPE_NEXT(name, type, attr) attr struct type *name##_RB_NEXT(struct type *)
'' TODO: #define RB_PROTOTYPE_PREV(name, type, attr) attr struct type *name##_RB_PREV(struct type *)
'' TODO: #define RB_PROTOTYPE_MINMAX(name, type, attr) attr struct type *name##_RB_MINMAX(struct name *, int)
'' TODO: #define RB_GENERATE(name, type, field, cmp) RB_GENERATE_INTERNAL(name, type, field, cmp,)
'' TODO: #define RB_GENERATE_STATIC(name, type, field, cmp) RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
'' TODO: #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) RB_GENERATE_INSERT_COLOR(name, type, field, attr) RB_GENERATE_REMOVE_COLOR(name, type, field, attr) RB_GENERATE_INSERT(name, type, field, cmp, attr) RB_GENERATE_REMOVE(name, type, field, attr) RB_GENERATE_FIND(name, type, field, cmp, attr) RB_GENERATE_NFIND(name, type, field, cmp, attr) RB_GENERATE_NEXT(name, type, field, attr) RB_GENERATE_PREV(name, type, field, attr) RB_GENERATE_MINMAX(name, type, field, attr)
'' TODO: #define RB_GENERATE_INSERT_COLOR(name, type, field, attr) attr void name##_RB_INSERT_COLOR(struct name *head, struct type *elm) { struct type *parent, *gparent, *tmp; while ((parent = RB_PARENT(elm, field)) != NULL && RB_COLOR(parent, field) == RB_RED) { gparent = RB_PARENT(parent, field); if (parent == RB_LEFT(gparent, field)) { tmp = RB_RIGHT(gparent, field); if (tmp && RB_COLOR(tmp, field) == RB_RED) { RB_COLOR(tmp, field) = RB_BLACK; RB_SET_BLACKRED(parent, gparent, field); elm = gparent; continue; } if (RB_RIGHT(parent, field) == elm) { RB_ROTATE_LEFT(head, parent, tmp, field); tmp = parent; parent = elm; elm = tmp; } RB_SET_BLACKRED(parent, gparent, field); RB_ROTATE_RIGHT(head, gparent, tmp, field); } else { tmp = RB_LEFT(gparent, field); if (tmp && RB_COLOR(tmp, field) == RB_RED) { RB_COLOR(tmp, field) = RB_BLACK; RB_SET_BLACKRED(parent, gparent, field); elm = gparent; continue; } if (RB_LEFT(parent, field) == elm) { RB_ROTATE_RIGHT(head, parent, tmp, field); tmp = parent; parent = elm; elm = tmp; } RB_SET_BLACKRED(parent, gparent, field); RB_ROTATE_LEFT(head, gparent, tmp, field); } } RB_COLOR(head->rbh_root, field) = RB_BLACK; }
'' TODO: #define RB_GENERATE_REMOVE_COLOR(name, type, field, attr) attr void name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) { struct type *tmp; while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && elm != RB_ROOT(head)) { if (RB_LEFT(parent, field) == elm) { tmp = RB_RIGHT(parent, field); if (RB_COLOR(tmp, field) == RB_RED) { RB_SET_BLACKRED(tmp, parent, field); RB_ROTATE_LEFT(head, parent, tmp, field); tmp = RB_RIGHT(parent, field); } if ((RB_LEFT(tmp, field) == NULL || RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && (RB_RIGHT(tmp, field) == NULL || RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { RB_COLOR(tmp, field) = RB_RED; elm = parent; parent = RB_PARENT(elm, field); } else { if (RB_RIGHT(tmp, field) == NULL || RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { struct type *oleft; if ((oleft = RB_LEFT(tmp, field)) != NULL) RB_COLOR(oleft, field) = RB_BLACK; RB_COLOR(tmp, field) = RB_RED; RB_ROTATE_RIGHT(head, tmp, oleft, field); tmp = RB_RIGHT(parent, field); } RB_COLOR(tmp, field) = RB_COLOR(parent, field); RB_COLOR(parent, field) = RB_BLACK; if (RB_RIGHT(tmp, field)) RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; RB_ROTATE_LEFT(head, parent, tmp, field); elm = RB_ROOT(head); break; } } else { tmp = RB_LEFT(parent, field); if (RB_COLOR(tmp, field) == RB_RED) { RB_SET_BLACKRED(tmp, parent, field); RB_ROTATE_RIGHT(head, parent, tmp, field); tmp = RB_LEFT(parent, field); } if ((RB_LEFT(tmp, field) == NULL || RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && (RB_RIGHT(tmp, field) == NULL || RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { RB_COLOR(tmp, field) = RB_RED; elm = parent; parent = RB_PARENT(elm, field); } else { if (RB_LEFT(tmp, field) == NULL || RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { struct type *oright; if ((oright = RB_RIGHT(tmp, field)) != NULL) RB_COLOR(oright, field) = RB_BLACK; RB_COLOR(tmp, field) = RB_RED; RB_ROTATE_LEFT(head, tmp, oright, field); tmp = RB_LEFT(parent, field); } RB_COLOR(tmp, field) = RB_COLOR(parent, field); RB_COLOR(parent, field) = RB_BLACK; if (RB_LEFT(tmp, field)) RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; RB_ROTATE_RIGHT(head, parent, tmp, field); elm = RB_ROOT(head); break; } } } if (elm) RB_COLOR(elm, field) = RB_BLACK; }
'' TODO: #define RB_GENERATE_REMOVE(name, type, field, attr) attr struct type * name##_RB_REMOVE(struct name *head, struct type *elm) { struct type *child, *parent, *old = elm; int color; if (RB_LEFT(elm, field) == NULL) child = RB_RIGHT(elm, field); else if (RB_RIGHT(elm, field) == NULL) child = RB_LEFT(elm, field); else { struct type *left; elm = RB_RIGHT(elm, field); while ((left = RB_LEFT(elm, field)) != NULL) elm = left; child = RB_RIGHT(elm, field); parent = RB_PARENT(elm, field); color = RB_COLOR(elm, field); if (child) RB_PARENT(child, field) = parent; if (parent) { if (RB_LEFT(parent, field) == elm) RB_LEFT(parent, field) = child; else RB_RIGHT(parent, field) = child; RB_AUGMENT(parent); } else RB_ROOT(head) = child; if (RB_PARENT(elm, field) == old) parent = elm; (elm)->field = (old)->field; if (RB_PARENT(old, field)) { if (RB_LEFT(RB_PARENT(old, field), field) == old) RB_LEFT(RB_PARENT(old, field), field) = elm; else RB_RIGHT(RB_PARENT(old, field), field) = elm; RB_AUGMENT(RB_PARENT(old, field)); } else RB_ROOT(head) = elm; RB_PARENT(RB_LEFT(old, field), field) = elm; if (RB_RIGHT(old, field)) RB_PARENT(RB_RIGHT(old, field), field) = elm; if (parent) { left = parent; do { RB_AUGMENT(left); } while ((left = RB_PARENT(left, field)) != NULL); } goto color; } parent = RB_PARENT(elm, field); color = RB_COLOR(elm, field); if (child) RB_PARENT(child, field) = parent; if (parent) { if (RB_LEFT(parent, field) == elm) RB_LEFT(parent, field) = child; else RB_RIGHT(parent, field) = child; RB_AUGMENT(parent); } else RB_ROOT(head) = child; color: if (color == RB_BLACK) name##_RB_REMOVE_COLOR(head, parent, child); return (old); }
'' TODO: #define RB_GENERATE_INSERT(name, type, field, cmp, attr) attr struct type * name##_RB_INSERT(struct name *head, struct type *elm) { struct type *tmp; struct type *parent = NULL; int comp = 0; tmp = RB_ROOT(head); while (tmp) { parent = tmp; comp = (cmp)(elm, parent); if (comp < 0) tmp = RB_LEFT(tmp, field); else if (comp > 0) tmp = RB_RIGHT(tmp, field); else return (tmp); } RB_SET(elm, parent, field); if (parent != NULL) { if (comp < 0) RB_LEFT(parent, field) = elm; else RB_RIGHT(parent, field) = elm; RB_AUGMENT(parent); } else RB_ROOT(head) = elm; name##_RB_INSERT_COLOR(head, elm); return (NULL); }
'' TODO: #define RB_GENERATE_FIND(name, type, field, cmp, attr) attr struct type * name##_RB_FIND(struct name *head, struct type *elm) { struct type *tmp = RB_ROOT(head); int comp; while (tmp) { comp = cmp(elm, tmp); if (comp < 0) tmp = RB_LEFT(tmp, field); else if (comp > 0) tmp = RB_RIGHT(tmp, field); else return (tmp); } return (NULL); }
'' TODO: #define RB_GENERATE_NFIND(name, type, field, cmp, attr) attr struct type * name##_RB_NFIND(struct name *head, struct type *elm) { struct type *tmp = RB_ROOT(head); struct type *res = NULL; int comp; while (tmp) { comp = cmp(elm, tmp); if (comp < 0) { res = tmp; tmp = RB_LEFT(tmp, field); } else if (comp > 0) tmp = RB_RIGHT(tmp, field); else return (tmp); } return (res); }
'' TODO: #define RB_GENERATE_NEXT(name, type, field, attr) attr struct type * name##_RB_NEXT(struct type *elm) { if (RB_RIGHT(elm, field)) { elm = RB_RIGHT(elm, field); while (RB_LEFT(elm, field)) elm = RB_LEFT(elm, field); } else { if (RB_PARENT(elm, field) && (elm == RB_LEFT(RB_PARENT(elm, field), field))) elm = RB_PARENT(elm, field); else { while (RB_PARENT(elm, field) && (elm == RB_RIGHT(RB_PARENT(elm, field), field))) elm = RB_PARENT(elm, field); elm = RB_PARENT(elm, field); } } return (elm); }
'' TODO: #define RB_GENERATE_PREV(name, type, field, attr) attr struct type * name##_RB_PREV(struct type *elm) { if (RB_LEFT(elm, field)) { elm = RB_LEFT(elm, field); while (RB_RIGHT(elm, field)) elm = RB_RIGHT(elm, field); } else { if (RB_PARENT(elm, field) && (elm == RB_RIGHT(RB_PARENT(elm, field), field))) elm = RB_PARENT(elm, field); else { while (RB_PARENT(elm, field) && (elm == RB_LEFT(RB_PARENT(elm, field), field))) elm = RB_PARENT(elm, field); elm = RB_PARENT(elm, field); } } return (elm); }
'' TODO: #define RB_GENERATE_MINMAX(name, type, field, attr) attr struct type * name##_RB_MINMAX(struct name *head, int val) { struct type *tmp = RB_ROOT(head); struct type *parent = NULL; while (tmp) { parent = tmp; if (val < 0) tmp = RB_LEFT(tmp, field); else tmp = RB_RIGHT(tmp, field); } return (parent); }
const RB_NEGINF = -1
const RB_INF = 1
'' TODO: #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
'' TODO: #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
'' TODO: #define RB_FIND(name, x, y) name##_RB_FIND(x, y)
'' TODO: #define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
'' TODO: #define RB_NEXT(name, x, y) name##_RB_NEXT(y)
'' TODO: #define RB_PREV(name, x, y) name##_RB_PREV(y)
'' TODO: #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
'' TODO: #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
'' TODO: #define RB_FOREACH(x, name, head) for ((x) = RB_MIN(name, head); (x) != NULL; (x) = name##_RB_NEXT(x))
'' TODO: #define RB_FOREACH_FROM(x, name, y) for ((x) = (y); ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); (x) = (y))
'' TODO: #define RB_FOREACH_SAFE(x, name, head, y) for ((x) = RB_MIN(name, head); ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); (x) = (y))
'' TODO: #define RB_FOREACH_REVERSE(x, name, head) for ((x) = RB_MAX(name, head); (x) != NULL; (x) = name##_RB_PREV(x))
'' TODO: #define RB_FOREACH_REVERSE_FROM(x, name, y) for ((x) = (y); ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); (x) = (y))
'' TODO: #define RB_FOREACH_REVERSE_SAFE(x, name, head, y) for ((x) = RB_MAX(name, head); ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); (x) = (y))
'' TODO: #define STATIC static
type lxw_row_t as ulong
type lxw_col_t as ushort
type lxw_boolean as long
enum
LXW_FALSE
LXW_TRUE
end enum
type lxw_error as long
enum
LXW_NO_ERROR = 0
LXW_ERROR_MEMORY_MALLOC_FAILED
LXW_ERROR_CREATING_XLSX_FILE
LXW_ERROR_CREATING_TMPFILE
LXW_ERROR_ZIP_FILE_OPERATION
LXW_ERROR_ZIP_FILE_ADD
LXW_ERROR_ZIP_CLOSE
LXW_ERROR_NULL_PARAMETER_IGNORED
LXW_ERROR_PARAMETER_VALIDATION
LXW_ERROR_SHEETNAME_LENGTH_EXCEEDED
LXW_ERROR_INVALID_SHEETNAME_CHARACTER
LXW_ERROR_SHEETNAME_ALREADY_USED
LXW_ERROR_128_STRING_LENGTH_EXCEEDED
LXW_ERROR_255_STRING_LENGTH_EXCEEDED
LXW_ERROR_MAX_STRING_LENGTH_EXCEEDED
LXW_ERROR_SHARED_STRING_INDEX_NOT_FOUND
LXW_ERROR_WORKSHEET_INDEX_OUT_OF_RANGE
LXW_ERROR_WORKSHEET_MAX_NUMBER_URLS_EXCEEDED
LXW_ERROR_IMAGE_DIMENSIONS
LXW_MAX_ERRNO
end enum
type lxw_datetime
year as long
month as long
day as long
hour as long
min as long
sec as double
end type
type lxw_custom_property_types as long
enum
LXW_CUSTOM_NONE
LXW_CUSTOM_STRING
LXW_CUSTOM_DOUBLE
LXW_CUSTOM_INTEGER
LXW_CUSTOM_BOOLEAN
LXW_CUSTOM_DATETIME
end enum
const LXW_SHEETNAME_MAX = 31
const LXW_MAX_SHEETNAME_LENGTH = ((LXW_SHEETNAME_MAX * 4) + 2) + 1
#define LXW_MAX_COL_NAME_LENGTH sizeof("$XFD")
#define LXW_MAX_ROW_NAME_LENGTH sizeof("$1048576")
#define LXW_MAX_CELL_NAME_LENGTH sizeof("$XFWD$1048576")
#define LXW_MAX_CELL_RANGE_LENGTH (LXW_MAX_CELL_NAME_LENGTH * 2)
#define LXW_MAX_FORMULA_RANGE_LENGTH (LXW_MAX_SHEETNAME_LENGTH + LXW_MAX_CELL_RANGE_LENGTH)
#define LXW_DATETIME_LENGTH sizeof("2016-12-12T23:00:00Z")
const LXW_EPOCH_1900 = 0
const LXW_EPOCH_1904 = 1
#define LXW_UINT32_T_LENGTH sizeof("4294967296")
const LXW_FILENAME_LENGTH = 128
const LXW_IGNORE = 1
#define LXW_SCHEMA_MS "http://schemas.microsoft.com/office/2006/relationships"
#define LXW_SCHEMA_ROOT "http://schemas.openxmlformats.org"
#define LXW_SCHEMA_DRAWING LXW_SCHEMA_ROOT "/drawingml/2006"
#define LXW_SCHEMA_OFFICEDOC LXW_SCHEMA_ROOT "/officeDocument/2006"
#define LXW_SCHEMA_PACKAGE LXW_SCHEMA_ROOT "/package/2006/relationships"
#define LXW_SCHEMA_DOCUMENT LXW_SCHEMA_ROOT "/officeDocument/2006/relationships"
#define LXW_SCHEMA_CONTENT LXW_SCHEMA_ROOT "/package/2006/content-types"
' ~ #define LXW_ERROR(message) fprintf(stderr, "[ERROR][%s:%d]: " message !"\n", __FILE__, __LINE__)
#define LXW_MEM_ERROR() LXW_ERROR("Memory allocation failed.")
#macro GOTO_LABEL_ON_MEM_ERROR(pointer, label)
if pointer = 0 then
LXW_MEM_ERROR()
'' TODO: goto label;
end if
#endmacro
#macro RETURN_ON_MEM_ERROR(pointer, error)
if pointer = 0 then
LXW_MEM_ERROR()
return error
end if
#endmacro
#macro RETURN_VOID_ON_MEM_ERROR(pointer)
if pointer = 0 then
LXW_MEM_ERROR()
return
end if
#endmacro
#macro RETURN_ON_ERROR(error)
if error then
return error
end if
#endmacro
#define LXW_WARN(message) fprintf(stderr, "[WARNING]: " message !"\n")
#define LXW_WARN_FORMAT(message) fprintf(stderr, "[WARNING]: " message !"\n")
#define LXW_WARN_FORMAT1(message, var) fprintf(stderr, "[WARNING]: " message !"\n", var)
#define LXW_WARN_FORMAT2(message, var1, var2) fprintf(stderr, "[WARNING]: " message !"\n", var1, var2)
#macro LXW_WARN_CAT_AXIS_ONLY(function)
if axis->is_category = 0 then
fprintf(stderr, "[WARNING]: " function !"() is only valid for category axes\n")
return
end if
#endmacro
#macro LXW_WARN_VALUE_AXIS_ONLY(function)
if axis->is_value = 0 then
fprintf(stderr, "[WARNING]: " function !"() is only valid for value axes\n")
return
end if
#endmacro
#macro LXW_WARN_DATE_AXIS_ONLY(function)
if axis->is_date = 0 then
fprintf(stderr, "[WARNING]: " function !"() is only valid for date axes\n")
return
end if
#endmacro
#macro LXW_WARN_CAT_AND_DATE_AXIS_ONLY(function)
if (axis->is_category = 0) andalso (axis->is_date = 0) then
fprintf(stderr, "[WARNING]: " function !"() is only valid for category and date axes\n")
return
end if
#endmacro
#macro LXW_WARN_VALUE_AND_DATE_AXIS_ONLY(function)
if (axis->is_value = 0) andalso (axis->is_date = 0) then
fprintf(stderr, "[WARNING]: " function !"() is only valid for value and date axes\n")
return
end if
#endmacro
#define LXW_UINT32_NETWORK(n) ((((((n) and &hFF) shl 24) or (((n) and &hFF00) shl 8)) or (((n) and &hFF0000) shr 8)) or (((n) and &hFF000000) shr 24))
#define LXW_UINT16_NETWORK(n) ((((n) and &h00FF) shl 8) or (((n) and &hFF00) shr 8))
#define lxw_snprintf __builtin_snprintf
#define lxw_strcpy(dest, src) lxw_snprintf(dest, sizeof(dest), "%s", src)
type lxw_format as lxw_format_
type lxw_formats
stqh_first as lxw_format ptr
stqh_last as lxw_format ptr ptr
end type
type lxw_tuple as lxw_tuple_
type lxw_tuples
stqh_first as lxw_tuple ptr
stqh_last as lxw_tuple ptr ptr
end type
type lxw_custom_property as lxw_custom_property_
type lxw_custom_properties
stqh_first as lxw_custom_property ptr
stqh_last as lxw_custom_property ptr ptr
end type
type lxw_tuple_list_pointers
stqe_next as lxw_tuple ptr
end type
type lxw_tuple_
key as zstring ptr
value as zstring ptr
list_pointers as lxw_tuple_list_pointers
end type
union lxw_custom_property_u
string as zstring ptr
number as double
integer as long
boolean as ubyte
datetime as lxw_datetime
end union
type lxw_custom_property_list_pointers
stqe_next as lxw_custom_property ptr
end type
type lxw_custom_property_
as lxw_custom_property_types type
name as zstring ptr
u as lxw_custom_property_u
list_pointers as lxw_custom_property_list_pointers
end type
type sst_element as sst_element_
type sst_rb_tree
rbh_root as sst_element ptr
end type
type sst_order_list
stqh_first as sst_element ptr
stqh_last as sst_element ptr ptr
end type
'' TODO: #define LXW_RB_GENERATE_ELEMENT(name, type, field, cmp) RB_GENERATE_INSERT_COLOR(name, type, field, static) RB_GENERATE_INSERT(name, type, field, cmp, static) struct lxw_rb_generate_element{int unused;}
type sst_element_sst_order_pointers
stqe_next as sst_element ptr
end type
type sst_element_sst_tree_pointers
rbe_left as sst_element ptr
rbe_right as sst_element ptr
rbe_parent as sst_element ptr
rbe_color as long
end type
type sst_element_
index as ulong
string as zstring ptr
sst_order_pointers as sst_element_sst_order_pointers
sst_tree_pointers as sst_element_sst_tree_pointers
end type
type lxw_sst
file as FILE ptr
string_count as ulong
unique_count as ulong
order_list as sst_order_list ptr
rb_tree as sst_rb_tree ptr
end type
declare function lxw_sst_new() as lxw_sst ptr
declare sub lxw_sst_free(byval sst as lxw_sst ptr)
declare function lxw_get_sst_index(byval sst as lxw_sst ptr, byval string as const zstring ptr) as sst_element ptr
declare sub lxw_sst_assemble_xml_file(byval self as lxw_sst ptr)
#define __LXW_CHART_H__
#define __LXW_FORMAT_H__
#define __LXW_HASH_TABLE_H__
#define LXW_FOREACH_ORDERED(elem, hash_table) STAILQ_FOREACH((elem), (hash_table)->order_list, lxw_hash_order_pointers)
type lxw_hash_element as lxw_hash_element_
type lxw_hash_order_list
stqh_first as lxw_hash_element ptr
stqh_last as lxw_hash_element ptr ptr
end type
type lxw_hash_bucket_list
slh_first as lxw_hash_element ptr
end type
type lxw_hash_table
num_buckets as ulong
used_buckets as ulong
unique_count as ulong
free_key as ubyte
free_value as ubyte
order_list as lxw_hash_order_list ptr
buckets as lxw_hash_bucket_list ptr ptr
end type
type lxw_hash_element_lxw_hash_order_pointers
stqe_next as lxw_hash_element ptr
end type
type lxw_hash_element_lxw_hash_list_pointers
sle_next as lxw_hash_element ptr
end type
type lxw_hash_element_
key as any ptr
value as any ptr
lxw_hash_order_pointers as lxw_hash_element_lxw_hash_order_pointers
lxw_hash_list_pointers as lxw_hash_element_lxw_hash_list_pointers
end type
declare function lxw_hash_key_exists(byval lxw_hash as lxw_hash_table ptr, byval key as any ptr, byval key_len as uinteger) as lxw_hash_element ptr
declare function lxw_insert_hash_element(byval lxw_hash as lxw_hash_table ptr, byval key as any ptr, byval value as any ptr, byval key_len as uinteger) as lxw_hash_element ptr
declare function lxw_hash_new(byval num_buckets as ulong, byval free_key as ubyte, byval free_value as ubyte) as lxw_hash_table ptr
declare sub lxw_hash_free(byval lxw_hash as lxw_hash_table ptr)
type lxw_color_t as long
const LXW_FORMAT_FIELD_LEN = 128
#define LXW_DEFAULT_FONT_NAME "Calibri"
const LXW_DEFAULT_FONT_FAMILY = 2
const LXW_DEFAULT_FONT_THEME = 1
const LXW_PROPERTY_UNSET = -1
const LXW_COLOR_UNSET = -1
const LXW_COLOR_MASK = &hFFFFFF
const LXW_MIN_FONT_SIZE = 1
const LXW_MAX_FONT_SIZE = 409
#macro LXW_FORMAT_FIELD_COPY(dst, src)
scope
strncpy(dst, src, LXW_FORMAT_FIELD_LEN - 1)
dst[(LXW_FORMAT_FIELD_LEN - 1)] = asc(!"\0")
end scope
#endmacro
type lxw_format_underlines as long
enum
LXW_UNDERLINE_SINGLE = 1
LXW_UNDERLINE_DOUBLE
LXW_UNDERLINE_SINGLE_ACCOUNTING
LXW_UNDERLINE_DOUBLE_ACCOUNTING
end enum
type lxw_format_scripts as long
enum
LXW_FONT_SUPERSCRIPT = 1
LXW_FONT_SUBSCRIPT
end enum
type lxw_format_alignments as long
enum
LXW_ALIGN_NONE = 0
LXW_ALIGN_LEFT
LXW_ALIGN_CENTER
LXW_ALIGN_RIGHT
LXW_ALIGN_FILL
LXW_ALIGN_JUSTIFY
LXW_ALIGN_CENTER_ACROSS
LXW_ALIGN_DISTRIBUTED
LXW_ALIGN_VERTICAL_TOP
LXW_ALIGN_VERTICAL_BOTTOM
LXW_ALIGN_VERTICAL_CENTER
LXW_ALIGN_VERTICAL_JUSTIFY
LXW_ALIGN_VERTICAL_DISTRIBUTED
end enum
type lxw_format_diagonal_types as long
enum
LXW_DIAGONAL_BORDER_UP = 1
LXW_DIAGONAL_BORDER_DOWN
LXW_DIAGONAL_BORDER_UP_DOWN
end enum
type lxw_defined_colors as long
enum
LXW_COLOR_BLACK = &h1000000
LXW_COLOR_BLUE = &h0000FF
LXW_COLOR_BROWN = &h800000
LXW_COLOR_CYAN = &h00FFFF
LXW_COLOR_GRAY = &h808080
LXW_COLOR_GREEN = &h008000
LXW_COLOR_LIME = &h00FF00
LXW_COLOR_MAGENTA = &hFF00FF
LXW_COLOR_NAVY = &h000080
LXW_COLOR_ORANGE = &hFF6600
LXW_COLOR_PINK = &hFF00FF
LXW_COLOR_PURPLE = &h800080
LXW_COLOR_RED = &hFF0000
LXW_COLOR_SILVER = &hC0C0C0
LXW_COLOR_WHITE = &hFFFFFF
LXW_COLOR_YELLOW = &hFFFF00
end enum
type lxw_format_patterns as long
enum
LXW_PATTERN_NONE = 0
LXW_PATTERN_SOLID
LXW_PATTERN_MEDIUM_GRAY
LXW_PATTERN_DARK_GRAY
LXW_PATTERN_LIGHT_GRAY
LXW_PATTERN_DARK_HORIZONTAL
LXW_PATTERN_DARK_VERTICAL
LXW_PATTERN_DARK_DOWN
LXW_PATTERN_DARK_UP
LXW_PATTERN_DARK_GRID
LXW_PATTERN_DARK_TRELLIS
LXW_PATTERN_LIGHT_HORIZONTAL
LXW_PATTERN_LIGHT_VERTICAL
LXW_PATTERN_LIGHT_DOWN
LXW_PATTERN_LIGHT_UP
LXW_PATTERN_LIGHT_GRID
LXW_PATTERN_LIGHT_TRELLIS
LXW_PATTERN_GRAY_125
LXW_PATTERN_GRAY_0625
end enum
type lxw_format_borders as long
enum
LXW_BORDER_NONE
LXW_BORDER_THIN
LXW_BORDER_MEDIUM
LXW_BORDER_DASHED
LXW_BORDER_DOTTED
LXW_BORDER_THICK
LXW_BORDER_DOUBLE
LXW_BORDER_HAIR
LXW_BORDER_MEDIUM_DASHED
LXW_BORDER_DASH_DOT
LXW_BORDER_MEDIUM_DASH_DOT
LXW_BORDER_DASH_DOT_DOT
LXW_BORDER_MEDIUM_DASH_DOT_DOT
LXW_BORDER_SLANT_DASH_DOT
end enum
type lxw_format_list_pointers
stqe_next as lxw_format ptr
end type
type lxw_format_
file as FILE ptr
xf_format_indices as lxw_hash_table ptr
num_xf_formats as ushort ptr
xf_index as long
dxf_index as long
num_format as zstring * 128
font_name as zstring * 128
font_scheme as zstring * 128
num_format_index as ushort
font_index as ushort
has_font as ubyte
has_dxf_font as ubyte
font_size as ushort
bold as ubyte
italic as ubyte
font_color as lxw_color_t
underline as ubyte
font_strikeout as ubyte
font_outline as ubyte
font_shadow as ubyte
font_script as ubyte
font_family as ubyte
font_charset as ubyte
font_condense as ubyte
font_extend as ubyte
theme as ubyte
hyperlink as ubyte
hidden as ubyte
locked as ubyte
text_h_align as ubyte
text_wrap as ubyte
text_v_align as ubyte
text_justlast as ubyte
rotation as short
fg_color as lxw_color_t
bg_color as lxw_color_t
pattern as ubyte
has_fill as ubyte
has_dxf_fill as ubyte
fill_index as long
fill_count as long
border_index as long
has_border as ubyte
has_dxf_border as ubyte
border_count as long
bottom as ubyte
diag_border as ubyte
diag_type as ubyte
left as ubyte
right as ubyte
top as ubyte
bottom_color as lxw_color_t
diag_color as lxw_color_t
left_color as lxw_color_t
right_color as lxw_color_t
top_color as lxw_color_t
indent as ubyte
shrink as ubyte
merge_range as ubyte
reading_order as ubyte
just_distrib as ubyte
color_indexed as ubyte
font_only as ubyte
list_pointers as lxw_format_list_pointers
end type
type lxw_font
font_name as zstring * 128
font_size as ushort
bold as ubyte
italic as ubyte
underline as ubyte
font_strikeout as ubyte
font_outline as ubyte
font_shadow as ubyte
font_script as ubyte
font_family as ubyte
font_charset as ubyte
font_condense as ubyte
font_extend as ubyte
font_color as lxw_color_t
end type
type lxw_border
bottom as ubyte
diag_border as ubyte
diag_type as ubyte
left as ubyte
right as ubyte
top as ubyte
bottom_color as lxw_color_t
diag_color as lxw_color_t
left_color as lxw_color_t
right_color as lxw_color_t
top_color as lxw_color_t
end type
type lxw_fill
fg_color as lxw_color_t
bg_color as lxw_color_t
pattern as ubyte
end type
declare function lxw_format_new() as lxw_format ptr
declare sub lxw_format_free(byval format as lxw_format ptr)
declare function lxw_format_get_xf_index(byval format as lxw_format ptr) as long
declare function lxw_format_get_font_key(byval format as lxw_format ptr) as lxw_font ptr
declare function lxw_format_get_border_key(byval format as lxw_format ptr) as lxw_border ptr
declare function lxw_format_get_fill_key(byval format as lxw_format ptr) as lxw_fill ptr
declare function lxw_format_check_color(byval color as lxw_color_t) as lxw_color_t
declare sub format_set_font_name(byval format as lxw_format ptr, byval font_name as const zstring ptr)
declare sub format_set_font_size(byval format as lxw_format ptr, byval size as ushort)
declare sub format_set_font_color(byval format as lxw_format ptr, byval color as lxw_color_t)
declare sub format_set_bold(byval format as lxw_format ptr)
declare sub format_set_italic(byval format as lxw_format ptr)