Subversion Repositories Kolibri OS

Rev

Rev 8856 | Rev 8958 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8834 Boppan 1
import re
8825 Boppan 2
import os
8837 Boppan 3
import argparse
8957 Boppan 4
import sys
8825 Boppan 5
 
8957 Boppan 6
""" TODO:
7
    - Add methods to dump stuff to file
8
"""
9
 
8834 Boppan 10
# Parameters
8837 Boppan 11
# Path to doxygen folder to make doxygen files in: -o 
8834 Boppan 12
doxygen_src_path = 'docs/doxygen'
8837 Boppan 13
# Remove generated doxygen files: --clean
14
clean_generated_stuff = False
15
# Dump all defined symbols: --dump
8834 Boppan 16
dump_symbols = False
8837 Boppan 17
# Print symbol stats: --stats
8834 Boppan 18
print_stats = False
8855 Boppan 19
# Do not write warnings file: --nowarn
20
enable_warnings = True
8825 Boppan 21
 
8837 Boppan 22
# Constants
23
link_root = "http://websvn.kolibrios.org/filedetails.php?repname=Kolibri+OS&path=/kernel/trunk"
24
 
8957 Boppan 25
# fasm keywords
26
keywords = [
27
	# Generic keywords
28
	"align",
29
	"equ",
30
	"org",
31
	"while",
32
	"load",
33
	"store",
34
	"times",
35
	"repeat",
36
	"virtual",
37
	"display",
38
	"err",
39
	"assert",
40
	"if",
41
	# Instructions
42
	"aaa",
43
	"aad",
44
	"aam",
45
	"aas",
46
	"adc",
47
	"adcx",
48
	"add",
49
	"addpd",
50
	"addps",
51
	"addsd",
52
	"addss",
53
	"addsubpd",
54
	"addsubps",
55
	"adox",
56
	"aesdec",
57
	"aesdeclast",
58
	"aesenc",
59
	"aesenclast",
60
	"aesimc",
61
	"aeskeygenassist",
62
	"and",
63
	"andn",
64
	"andnpd",
65
	"andnps",
66
	"andpd",
67
	"andps",
68
	"arpl",
69
	"bextr",
70
	"blendpd",
71
	"blendps",
72
	"blendvpd",
73
	"blendvps",
74
	"blsi",
75
	"blsmsk",
76
	"blsr",
77
	"bndcl",
78
	"bndcn",
79
	"bndcu",
80
	"bndldx",
81
	"bndmk",
82
	"bndmov",
83
	"bndstx",
84
	"bound",
85
	"bsf",
86
	"bsr",
87
	"bswap",
88
	"bt",
89
	"btc",
90
	"btr",
91
	"bts",
92
	"bzhi",
93
	"call",
94
	"cbw",
95
	"cdq",
96
	"cdqe",
97
	"clac",
98
	"clc",
99
	"cld",
100
	"cldemote",
101
	"clflush",
102
	"clflushopt",
103
	"cli",
104
	"clts",
105
	"clwb",
106
	"cmc",
107
	"cmova",
108
	"cmovae",
109
	"cmovb",
110
	"cmovbe",
111
	"cmovc",
112
	"cmove",
113
	"cmovg",
114
	"cmovge",
115
	"cmovl",
116
	"cmovle",
117
	"cmovna",
118
	"cmovnae",
119
	"cmovnb",
120
	"cmovnbe",
121
	"cmovnc",
122
	"cmovne",
123
	"cmovng",
124
	"cmovnge",
125
	"cmovnl",
126
	"cmovnle",
127
	"cmovno",
128
	"cmovnp",
129
	"cmovns",
130
	"cmovnz",
131
	"cmovo",
132
	"cmovp",
133
	"cmovpe",
134
	"cmovpo",
135
	"cmovs",
136
	"cmovz",
137
	"cmp",
138
	"cmppd",
139
	"cmpps",
140
	"cmps",
141
	"cmpsb",
142
	"cmpsd",
143
	"cmpsd",
144
	"cmpsq",
145
	"cmpss",
146
	"cmpsw",
147
	"cmpxchg",
148
	"cmpxchg16b",
149
	"cmpxchg8b",
150
	"comisd",
151
	"comiss",
152
	"cpuid",
153
	"cqo",
154
	"crc32",
155
	"cvtdq2pd",
156
	"cvtdq2ps",
157
	"cvtpd2dq",
158
	"cvtpd2pi",
159
	"cvtpd2ps",
160
	"cvtpi2pd",
161
	"cvtpi2ps",
162
	"cvtps2dq",
163
	"cvtps2pd",
164
	"cvtps2pi",
165
	"cvtsd2si",
166
	"cvtsd2ss",
167
	"cvtsi2sd",
168
	"cvtsi2ss",
169
	"cvtss2sd",
170
	"cvtss2si",
171
	"cvttpd2dq",
172
	"cvttpd2pi",
173
	"cvttps2dq",
174
	"cvttps2pi",
175
	"cvttsd2si",
176
	"cvttss2si",
177
	"cwd",
178
	"cwde",
179
	"daa",
180
	"das",
181
	"dec",
182
	"div",
183
	"divpd",
184
	"divps",
185
	"divsd",
186
	"divss",
187
	"dppd",
188
	"dpps",
189
	"emms",
190
	"enter",
191
	"extractps",
192
	"f2xm1",
193
	"fabs",
194
	"fadd",
195
	"faddp",
196
	"fbld",
197
	"fbstp",
198
	"fchs",
199
	"fclex",
200
	"fcmova",
201
	"fcmovae",
202
	"fcmovb",
203
	"fcmovbe",
204
	"fcmovc",
205
	"fcmove",
206
	"fcmovg",
207
	"fcmovge",
208
	"fcmovl",
209
	"fcmovle",
210
	"fcmovna",
211
	"fcmovnae",
212
	"fcmovnb",
213
	"fcmovnbe",
214
	"fcmovnc",
215
	"fcmovne",
216
	"fcmovng",
217
	"fcmovnge",
218
	"fcmovnl",
219
	"fcmovnle",
220
	"fcmovno",
221
	"fcmovnp",
222
	"fcmovns",
223
	"fcmovnz",
224
	"fcmovo",
225
	"fcmovp",
226
	"fcmovpe",
227
	"fcmovpo",
228
	"fcmovs",
229
	"fcmovz",
230
	"fcom",
231
	"fcomi",
232
	"fcomip",
233
	"fcomp",
234
	"fcompp",
235
	"fcos",
236
	"fdecstp",
237
	"fdiv",
238
	"fdivp",
239
	"fdivr",
240
	"fdivrp",
241
	"ffree",
242
	"fiadd",
243
	"ficom",
244
	"ficomp",
245
	"fidiv",
246
	"fidivr",
247
	"fild",
248
	"fimul",
249
	"fincstp",
250
	"finit",
251
	"fist",
252
	"fistp",
253
	"fisttp",
254
	"fisub",
255
	"fisubr",
256
	"fld",
257
	"fld1",
258
	"fldcw",
259
	"fldenv",
260
	"fldl2e",
261
	"fldl2t",
262
	"fldlg2",
263
	"fldln2",
264
	"fldpi",
265
	"fldz",
266
	"fmul",
267
	"fmulp",
268
	"fnclex",
269
	"fninit",
270
	"fnop",
271
	"fnsave",
272
	"fnstcw",
273
	"fnstenv",
274
	"fnstsw",
275
	"fpatan",
276
	"fprem",
277
	"fprem1",
278
	"fptan",
279
	"frndint",
280
	"frstor",
281
	"fsave",
282
	"fscale",
283
	"fsin",
284
	"fsincos",
285
	"fsqrt",
286
	"fst",
287
	"fstcw",
288
	"fstenv",
289
	"fstp",
290
	"fstsw",
291
	"fsub",
292
	"fsubp",
293
	"fsubr",
294
	"fsubrp",
295
	"ftst",
296
	"fucom",
297
	"fucomi",
298
	"fucomip",
299
	"fucomp",
300
	"fucompp",
301
	"fwait",
302
	"fxam",
303
	"fxch",
304
	"fxrstor",
305
	"fxsave",
306
	"fxtract",
307
	"fyl2x",
308
	"fyl2xp1",
309
	"gf2p8affineinvqb",
310
	"gf2p8affineqb",
311
	"gf2p8mulb",
312
	"haddpd",
313
	"haddps",
314
	"hlt",
315
	"hsubpd",
316
	"hsubps",
317
	"idiv",
318
	"imul",
319
	"in",
320
	"inc",
321
	"ins",
322
	"insb",
323
	"insd",
324
	"insertps",
325
	"insw",
326
	"int",
327
	"int1",
328
	"int3",
329
	"into",
330
	"invd",
331
	"invlpg",
332
	"invpcid",
333
	"iret",
334
	"iretd",
335
	"jmp",
336
	"ja",
337
	"jae",
338
	"jb",
339
	"jbe",
340
	"jc",
341
	"jcxz",
342
	"jecxz",
343
	"je",
344
	"jg",
345
	"jge",
346
	"jl",
347
	"jle",
348
	"jna",
349
	"jnae",
350
	"jnb",
351
	"jnbe",
352
	"jnc",
353
	"jne",
354
	"jng",
355
	"jnge",
356
	"jnl",
357
	"jnle",
358
	"jno",
359
	"jnp",
360
	"jns",
361
	"jnz",
362
	"jo",
363
	"jp",
364
	"jpe",
365
	"jpo",
366
	"js",
367
	"jz",
368
	"kaddb",
369
	"kaddd",
370
	"kaddq",
371
	"kaddw",
372
	"kandb",
373
	"kandd",
374
	"kandnb",
375
	"kandnd",
376
	"kandnq",
377
	"kandnw",
378
	"kandq",
379
	"kandw",
380
	"kmovb",
381
	"kmovd",
382
	"kmovq",
383
	"kmovw",
384
	"knotb",
385
	"knotd",
386
	"knotq",
387
	"knotw",
388
	"korb",
389
	"kord",
390
	"korq",
391
	"kortestb",
392
	"kortestd",
393
	"kortestq",
394
	"kortestw",
395
	"korw",
396
	"kshiftlb",
397
	"kshiftld",
398
	"kshiftlq",
399
	"kshiftlw",
400
	"kshiftrb",
401
	"kshiftrd",
402
	"kshiftrq",
403
	"kshiftrw",
404
	"ktestb",
405
	"ktestd",
406
	"ktestq",
407
	"ktestw",
408
	"kunpckbw",
409
	"kunpckdq",
410
	"kunpckwd",
411
	"kxnorb",
412
	"kxnord",
413
	"kxnorq",
414
	"kxnorw",
415
	"kxorb",
416
	"kxord",
417
	"kxorq",
418
	"kxorw",
419
	"lahf",
420
	"lar",
421
	"lddqu",
422
	"ldmxcsr",
423
	"lds",
424
	"lea",
425
	"leave",
426
	"les",
427
	"lfence",
428
	"lfs",
429
	"lgdt",
430
	"lgs",
431
	"lidt",
432
	"lldt",
433
	"lmsw",
434
	"lock",
435
	"lods",
436
	"lodsb",
437
	"lodsd",
438
	"lodsq",
439
	"lodsw",
440
	"loop",
441
	"loopa",
442
	"loopae",
443
	"loopb",
444
	"loopbe",
445
	"loopc",
446
	"loope",
447
	"loopg",
448
	"loopge",
449
	"loopl",
450
	"loople",
451
	"loopna",
452
	"loopnae",
453
	"loopnb",
454
	"loopnbe",
455
	"loopnc",
456
	"loopne",
457
	"loopng",
458
	"loopnge",
459
	"loopnl",
460
	"loopnle",
461
	"loopno",
462
	"loopnp",
463
	"loopns",
464
	"loopnz",
465
	"loopo",
466
	"loopp",
467
	"looppe",
468
	"looppo",
469
	"loops",
470
	"loopz",
471
	"lsl",
472
	"lss",
473
	"ltr",
474
	"lzcnt",
475
	"maskmovdqu",
476
	"maskmovq",
477
	"maxpd",
478
	"maxps",
479
	"maxsd",
480
	"maxss",
481
	"mfence",
482
	"minpd",
483
	"minps",
484
	"minsd",
485
	"minss",
486
	"monitor",
487
	"mov",
488
	"movapd",
489
	"movaps",
490
	"movbe",
491
	"movd",
492
	"movddup",
493
	"movdir64b",
494
	"movdiri",
495
	"movdq2q",
496
	"movdqa",
497
	"movdqu",
498
	"movhlps",
499
	"movhpd",
500
	"movhps",
501
	"movlhps",
502
	"movlpd",
503
	"movlps",
504
	"movmskpd",
505
	"movmskps",
506
	"movntdq",
507
	"movntdqa",
508
	"movnti",
509
	"movntpd",
510
	"movntps",
511
	"movntq",
512
	"movq",
513
	"movq",
514
	"movq2dq",
515
	"movs",
516
	"movsb",
517
	"movsd",
518
	"movsd",
519
	"movshdup",
520
	"movsldup",
521
	"movsq",
522
	"movss",
523
	"movsw",
524
	"movsx",
525
	"movsxd",
526
	"movupd",
527
	"movups",
528
	"movzx",
529
	"mpsadbw",
530
	"mul",
531
	"mulpd",
532
	"mulps",
533
	"mulsd",
534
	"mulss",
535
	"mulx",
536
	"mwait",
537
	"neg",
538
	"nop",
539
	"not",
540
	"or",
541
	"orpd",
542
	"orps",
543
	"out",
544
	"outs",
545
	"outsb",
546
	"outsd",
547
	"outsw",
548
	"pabsb",
549
	"pabsd",
550
	"pabsq",
551
	"pabsw",
552
	"packssdw",
553
	"packsswb",
554
	"packusdw",
555
	"packuswb",
556
	"paddb",
557
	"paddd",
558
	"paddq",
559
	"paddsb",
560
	"paddsw",
561
	"paddusb",
562
	"paddusw",
563
	"paddw",
564
	"palignr",
565
	"pand",
566
	"pandn",
567
	"pause",
568
	"pavgb",
569
	"pavgw",
570
	"pblendvb",
571
	"pblendw",
572
	"pclmulqdq",
573
	"pcmpeqb",
574
	"pcmpeqd",
575
	"pcmpeqq",
576
	"pcmpeqw",
577
	"pcmpestri",
578
	"pcmpestrm",
579
	"pcmpgtb",
580
	"pcmpgtd",
581
	"pcmpgtq",
582
	"pcmpgtw",
583
	"pcmpistri",
584
	"pcmpistrm",
585
	"pdep",
586
	"pext",
587
	"pextrb",
588
	"pextrd",
589
	"pextrq",
590
	"pextrw",
591
	"phaddd",
592
	"phaddsw",
593
	"phaddw",
594
	"phminposuw",
595
	"phsubd",
596
	"phsubsw",
597
	"phsubw",
598
	"pinsrb",
599
	"pinsrd",
600
	"pinsrq",
601
	"pinsrw",
602
	"pmaddubsw",
603
	"pmaddwd",
604
	"pmaxsb",
605
	"pmaxsd",
606
	"pmaxsq",
607
	"pmaxsw",
608
	"pmaxub",
609
	"pmaxud",
610
	"pmaxuq",
611
	"pmaxuw",
612
	"pminsb",
613
	"pminsd",
614
	"pminsq",
615
	"pminsw",
616
	"pminub",
617
	"pminud",
618
	"pminuq",
619
	"pminuw",
620
	"pmovmskb",
621
	"pmovsx",
622
	"pmovzx",
623
	"pmuldq",
624
	"pmulhrsw",
625
	"pmulhuw",
626
	"pmulhw",
627
	"pmulld",
628
	"pmullq",
629
	"pmullw",
630
	"pmuludq",
631
	"pop",
632
	"popa",
633
	"popad",
634
	"popcnt",
635
	"popf",
636
	"popfd",
637
	"popfq",
638
	"por",
639
	"prefetchw",
640
	"prefetchh",
641
	"psadbw",
642
	"pshufb",
643
	"pshufd",
644
	"pshufhw",
645
	"pshuflw",
646
	"pshufw",
647
	"psignb",
648
	"psignd",
649
	"psignw",
650
	"pslld",
651
	"pslldq",
652
	"psllq",
653
	"psllw",
654
	"psrad",
655
	"psraq",
656
	"psraw",
657
	"psrld",
658
	"psrldq",
659
	"psrlq",
660
	"psrlw",
661
	"psubb",
662
	"psubd",
663
	"psubq",
664
	"psubsb",
665
	"psubsw",
666
	"psubusb",
667
	"psubusw",
668
	"psubw",
669
	"ptest",
670
	"ptwrite",
671
	"punpckhbw",
672
	"punpckhdq",
673
	"punpckhqdq",
674
	"punpckhwd",
675
	"punpcklbw",
676
	"punpckldq",
677
	"punpcklqdq",
678
	"punpcklwd",
679
	"push",
680
	"pushw",
681
	"pushd",
682
	"pusha",
683
	"pushad",
684
	"pushf",
685
	"pushfd",
686
	"pushfq",
687
	"pxor",
688
	"rcl",
689
	"rcpps",
690
	"rcpss",
691
	"rcr",
692
	"rdfsbase",
693
	"rdgsbase",
694
	"rdmsr",
695
	"rdpid",
696
	"rdpkru",
697
	"rdpmc",
698
	"rdrand",
699
	"rdseed",
700
	"rdtsc",
701
	"rdtscp",
702
	"rep",
703
	"repe",
704
	"repne",
705
	"repnz",
706
	"repz",
707
	"ret",
708
	"rol",
709
	"ror",
710
	"rorx",
711
	"roundpd",
712
	"roundps",
713
	"roundsd",
714
	"roundss",
715
	"rsm",
716
	"rsqrtps",
717
	"rsqrtss",
718
	"sahf",
719
	"sal",
720
	"sar",
721
	"sarx",
722
	"sbb",
723
	"scas",
724
	"scasb",
725
	"scasd",
726
	"scasw",
727
	"seta",
728
	"setae",
729
	"setb",
730
	"setbe",
731
	"setc",
732
	"sete",
733
	"setg",
734
	"setge",
735
	"setl",
736
	"setle",
737
	"setna",
738
	"setnae",
739
	"setnb",
740
	"setnbe",
741
	"setnc",
742
	"setne",
743
	"setng",
744
	"setnge",
745
	"setnl",
746
	"setnle",
747
	"setno",
748
	"setnp",
749
	"setns",
750
	"setnz",
751
	"seto",
752
	"setp",
753
	"setpe",
754
	"setpo",
755
	"sets",
756
	"setz",
757
	"sfence",
758
	"sgdt",
759
	"sha1msg1",
760
	"sha1msg2",
761
	"sha1nexte",
762
	"sha1rnds4",
763
	"sha256msg1",
764
	"sha256msg2",
765
	"sha256rnds2",
766
	"shl",
767
	"shld",
768
	"shlx",
769
	"shr",
770
	"shrd",
771
	"shrx",
772
	"shufpd",
773
	"shufps",
774
	"sidt",
775
	"sldt",
776
	"smsw",
777
	"sqrtpd",
778
	"sqrtps",
779
	"sqrtsd",
780
	"sqrtss",
781
	"stac",
782
	"stc",
783
	"std",
784
	"sti",
785
	"stmxcsr",
786
	"stos",
787
	"stosb",
788
	"stosd",
789
	"stosq",
790
	"stosw",
791
	"str",
792
	"sub",
793
	"subpd",
794
	"subps",
795
	"subsd",
796
	"subss",
797
	"swapgs",
798
	"syscall",
799
	"sysenter",
800
	"sysexit",
801
	"sysret",
802
	"test",
803
	"tpause",
804
	"tzcnt",
805
	"ucomisd",
806
	"ucomiss",
807
	"ud",
808
	"umonitor",
809
	"umwait",
810
	"unpckhpd",
811
	"unpckhps",
812
	"unpcklpd",
813
	"unpcklps",
814
	"valignd",
815
	"valignq",
816
	"vblendmpd",
817
	"vblendmps",
818
	"vbroadcast",
819
	"vcompresspd",
820
	"vcompressps",
821
	"vcvtpd2qq",
822
	"vcvtpd2udq",
823
	"vcvtpd2uqq",
824
	"vcvtph2ps",
825
	"vcvtps2ph",
826
	"vcvtps2qq",
827
	"vcvtps2udq",
828
	"vcvtps2uqq",
829
	"vcvtqq2pd",
830
	"vcvtqq2ps",
831
	"vcvtsd2usi",
832
	"vcvtss2usi",
833
	"vcvttpd2qq",
834
	"vcvttpd2udq",
835
	"vcvttpd2uqq",
836
	"vcvttps2qq",
837
	"vcvttps2udq",
838
	"vcvttps2uqq",
839
	"vcvttsd2usi",
840
	"vcvttss2usi",
841
	"vcvtudq2pd",
842
	"vcvtudq2ps",
843
	"vcvtuqq2pd",
844
	"vcvtuqq2ps",
845
	"vcvtusi2sd",
846
	"vcvtusi2ss",
847
	"vdbpsadbw",
848
	"verr",
849
	"verw",
850
	"vexpandpd",
851
	"vexpandps",
852
	"vextractf128",
853
	"vextractf32x4",
854
	"vextractf32x8",
855
	"vextractf64x2",
856
	"vextractf64x4",
857
	"vextracti128",
858
	"vextracti32x4",
859
	"vextracti32x8",
860
	"vextracti64x2",
861
	"vextracti64x4",
862
	"vfixupimmpd",
863
	"vfixupimmps",
864
	"vfixupimmsd",
865
	"vfixupimmss",
866
	"vfmadd132pd",
867
	"vfmadd132ps",
868
	"vfmadd132sd",
869
	"vfmadd132ss",
870
	"vfmadd213pd",
871
	"vfmadd213ps",
872
	"vfmadd213sd",
873
	"vfmadd213ss",
874
	"vfmadd231pd",
875
	"vfmadd231ps",
876
	"vfmadd231sd",
877
	"vfmadd231ss",
878
	"vfmaddsub132pd",
879
	"vfmaddsub132ps",
880
	"vfmaddsub213pd",
881
	"vfmaddsub213ps",
882
	"vfmaddsub231pd",
883
	"vfmaddsub231ps",
884
	"vfmsub132pd",
885
	"vfmsub132ps",
886
	"vfmsub132sd",
887
	"vfmsub132ss",
888
	"vfmsub213pd",
889
	"vfmsub213ps",
890
	"vfmsub213sd",
891
	"vfmsub213ss",
892
	"vfmsub231pd",
893
	"vfmsub231ps",
894
	"vfmsub231sd",
895
	"vfmsub231ss",
896
	"vfmsubadd132pd",
897
	"vfmsubadd132ps",
898
	"vfmsubadd213pd",
899
	"vfmsubadd213ps",
900
	"vfmsubadd231pd",
901
	"vfmsubadd231ps",
902
	"vfnmadd132pd",
903
	"vfnmadd132ps",
904
	"vfnmadd132sd",
905
	"vfnmadd132ss",
906
	"vfnmadd213pd",
907
	"vfnmadd213ps",
908
	"vfnmadd213sd",
909
	"vfnmadd213ss",
910
	"vfnmadd231pd",
911
	"vfnmadd231ps",
912
	"vfnmadd231sd",
913
	"vfnmadd231ss",
914
	"vfnmsub132pd",
915
	"vfnmsub132ps",
916
	"vfnmsub132sd",
917
	"vfnmsub132ss",
918
	"vfnmsub213pd",
919
	"vfnmsub213ps",
920
	"vfnmsub213sd",
921
	"vfnmsub213ss",
922
	"vfnmsub231pd",
923
	"vfnmsub231ps",
924
	"vfnmsub231sd",
925
	"vfnmsub231ss",
926
	"vfpclasspd",
927
	"vfpclassps",
928
	"vfpclasssd",
929
	"vfpclassss",
930
	"vgatherdpd",
931
	"vgatherdpd",
932
	"vgatherdps",
933
	"vgatherdps",
934
	"vgatherqpd",
935
	"vgatherqpd",
936
	"vgatherqps",
937
	"vgatherqps",
938
	"vgetexppd",
939
	"vgetexpps",
940
	"vgetexpsd",
941
	"vgetexpss",
942
	"vgetmantpd",
943
	"vgetmantps",
944
	"vgetmantsd",
945
	"vgetmantss",
946
	"vinsertf128",
947
	"vinsertf32x4",
948
	"vinsertf32x8",
949
	"vinsertf64x2",
950
	"vinsertf64x4",
951
	"vinserti128",
952
	"vinserti32x4",
953
	"vinserti32x8",
954
	"vinserti64x2",
955
	"vinserti64x4",
956
	"vmaskmov",
957
	"vmovdqa32",
958
	"vmovdqa64",
959
	"vmovdqu16",
960
	"vmovdqu32",
961
	"vmovdqu64",
962
	"vmovdqu8",
963
	"vpblendd",
964
	"vpblendmb",
965
	"vpblendmd",
966
	"vpblendmq",
967
	"vpblendmw",
968
	"vpbroadcast",
969
	"vpbroadcastb",
970
	"vpbroadcastd",
971
	"vpbroadcastm",
972
	"vpbroadcastq",
973
	"vpbroadcastw",
974
	"vpcmpb",
975
	"vpcmpd",
976
	"vpcmpq",
977
	"vpcmpub",
978
	"vpcmpud",
979
	"vpcmpuq",
980
	"vpcmpuw",
981
	"vpcmpw",
982
	"vpcompressd",
983
	"vpcompressq",
984
	"vpconflictd",
985
	"vpconflictq",
986
	"vperm2f128",
987
	"vperm2i128",
988
	"vpermb",
989
	"vpermd",
990
	"vpermi2b",
991
	"vpermi2d",
992
	"vpermi2pd",
993
	"vpermi2ps",
994
	"vpermi2q",
995
	"vpermi2w",
996
	"vpermilpd",
997
	"vpermilps",
998
	"vpermpd",
999
	"vpermps",
1000
	"vpermq",
1001
	"vpermt2b",
1002
	"vpermt2d",
1003
	"vpermt2pd",
1004
	"vpermt2ps",
1005
	"vpermt2q",
1006
	"vpermt2w",
1007
	"vpermw",
1008
	"vpexpandd",
1009
	"vpexpandq",
1010
	"vpgatherdd",
1011
	"vpgatherdd",
1012
	"vpgatherdq",
1013
	"vpgatherdq",
1014
	"vpgatherqd",
1015
	"vpgatherqd",
1016
	"vpgatherqq",
1017
	"vpgatherqq",
1018
	"vplzcntd",
1019
	"vplzcntq",
1020
	"vpmadd52huq",
1021
	"vpmadd52luq",
1022
	"vpmaskmov",
1023
	"vpmovb2m",
1024
	"vpmovd2m",
1025
	"vpmovdb",
1026
	"vpmovdw",
1027
	"vpmovm2b",
1028
	"vpmovm2d",
1029
	"vpmovm2q",
1030
	"vpmovm2w",
1031
	"vpmovq2m",
1032
	"vpmovqb",
1033
	"vpmovqd",
1034
	"vpmovqw",
1035
	"vpmovsdb",
1036
	"vpmovsdw",
1037
	"vpmovsqb",
1038
	"vpmovsqd",
1039
	"vpmovsqw",
1040
	"vpmovswb",
1041
	"vpmovusdb",
1042
	"vpmovusdw",
1043
	"vpmovusqb",
1044
	"vpmovusqd",
1045
	"vpmovusqw",
1046
	"vpmovuswb",
1047
	"vpmovw2m",
1048
	"vpmovwb",
1049
	"vpmultishiftqb",
1050
	"vprold",
1051
	"vprolq",
1052
	"vprolvd",
1053
	"vprolvq",
1054
	"vprord",
1055
	"vprorq",
1056
	"vprorvd",
1057
	"vprorvq",
1058
	"vpscatterdd",
1059
	"vpscatterdq",
1060
	"vpscatterqd",
1061
	"vpscatterqq",
1062
	"vpsllvd",
1063
	"vpsllvq",
1064
	"vpsllvw",
1065
	"vpsravd",
1066
	"vpsravq",
1067
	"vpsravw",
1068
	"vpsrlvd",
1069
	"vpsrlvq",
1070
	"vpsrlvw",
1071
	"vpternlogd",
1072
	"vpternlogq",
1073
	"vptestmb",
1074
	"vptestmd",
1075
	"vptestmq",
1076
	"vptestmw",
1077
	"vptestnmb",
1078
	"vptestnmd",
1079
	"vptestnmq",
1080
	"vptestnmw",
1081
	"vrangepd",
1082
	"vrangeps",
1083
	"vrangesd",
1084
	"vrangess",
1085
	"vrcp14pd",
1086
	"vrcp14ps",
1087
	"vrcp14sd",
1088
	"vrcp14ss",
1089
	"vreducepd",
1090
	"vreduceps",
1091
	"vreducesd",
1092
	"vreducess",
1093
	"vrndscalepd",
1094
	"vrndscaleps",
1095
	"vrndscalesd",
1096
	"vrndscaless",
1097
	"vrsqrt14pd",
1098
	"vrsqrt14ps",
1099
	"vrsqrt14sd",
1100
	"vrsqrt14ss",
1101
	"vscalefpd",
1102
	"vscalefps",
1103
	"vscalefsd",
1104
	"vscalefss",
1105
	"vscatterdpd",
1106
	"vscatterdps",
1107
	"vscatterqpd",
1108
	"vscatterqps",
1109
	"vshuff32x4",
1110
	"vshuff64x2",
1111
	"vshufi32x4",
1112
	"vshufi64x2",
1113
	"vtestpd",
1114
	"vtestps",
1115
	"vzeroall",
1116
	"vzeroupper",
1117
	"wait",
1118
	"wbinvd",
1119
	"wrfsbase",
1120
	"wrgsbase",
1121
	"wrmsr",
1122
	"wrpkru",
1123
	"xabort",
1124
	"xacquire",
1125
	"xadd",
1126
	"xbegin",
1127
	"xchg",
1128
	"xend",
1129
	"xgetbv",
1130
	"xlat",
1131
	"xlatb",
1132
	"xor",
1133
	"xorpd",
1134
	"xorps",
1135
	"xrelease",
1136
	"xrstor",
1137
	"xrstors",
1138
	"xsave",
1139
	"xsavec",
1140
	"xsaveopt",
1141
	"xsaves",
1142
	"xsetbv",
1143
	"xtest"
1144
]
1145
 
1146
fasm_types = [
1147
	"db", "rb",
1148
	"dw", "rw",
1149
	"dd", "rd",
1150
	"dp", "rp",
1151
	"df", "rf",
1152
	"dq", "rq",
1153
	"dt", "rt",
1154
	"du",
1155
]
1156
 
8855 Boppan 1157
# Warning list
1158
warnings = ""
1159
 
8837 Boppan 1160
# Parse arguments
1161
parser = argparse.ArgumentParser()
1162
parser.add_argument("-o", help="Doxygen output folder")
1163
parser.add_argument("--clean", help="Remove generated files", action="store_true")
1164
parser.add_argument("--dump", help="Dump all defined symbols", action="store_true")
1165
parser.add_argument("--stats", help="Print symbol stats", action="store_true")
8855 Boppan 1166
parser.add_argument("--nowarn", help="Do not write warnings file", action="store_true")
8837 Boppan 1167
args = parser.parse_args()
1168
doxygen_src_path = args.o if args.o else 'docs/doxygen'
1169
clean_generated_stuff = args.clean
1170
dump_symbols = args.dump
1171
print_stats = args.stats
8855 Boppan 1172
enable_warnings = not args.nowarn
8837 Boppan 1173
 
8957 Boppan 1174
# Variables, functions, labels, macros, structure types
1175
elements = []
1176
# Names of macroses
1177
macro_names = []
1178
# Names of structs
1179
struct_names = []
1180
# Equated constant names (name = value)
1181
equated_constant_names = []
1182
# Literally equated constant names (name equ value)
1183
equ_names = []
8825 Boppan 1184
 
8957 Boppan 1185
class LegacyAsmReader:
1186
	def __init__(self, file):
1187
		self.file = file
1188
		self.lines = open(file, "r", encoding="utf-8").readlines()
1189
		self.line_idx = 0
1190
		self.i = 0
1191
 
1192
	def curr(self):
1193
		try: return self.lines[self.line_idx][self.i]
1194
		except: return ''
1195
 
1196
	def step(self):
1197
		c = self.curr()
1198
		self.i += 1
1199
		# Wrap the line if '\\' followed by whitespaces and/or comment
1200
		while self.curr() == '\\':
1201
			i_of_backslash = self.i
1202
			self.i += 1
1203
			while self.curr().isspace():
1204
				self.i += 1
1205
			if self.curr() == ';' or self.curr() == '':
1206
				self.line_idx += 1
1207
				self.i = 0
1208
			else:
1209
				# There's something other than a comment after the backslash
1210
				# So don't interpret the backslash as a line wrap
1211
				self.i = i_of_backslash
1212
				break
1213
		return c
1214
 
1215
	def nextline(self):
1216
		c = self.curr()
1217
		while c != '':
1218
			c = self.step()
1219
		self.line_idx += 1
1220
		self.i = 0
1221
 
1222
	def no_lines(self):
1223
		if self.line_idx >= len(self.lines):
1224
			return True
1225
		return False
1226
 
1227
	def location(self):
1228
		return f"{self.file}:{self.line_idx + 1}"
1229
 
1230
	def skip_spaces(self):
1231
		while self.curr().isspace():
1232
			self.step()
1233
 
1234
class AsmReaderRecognizingStrings(LegacyAsmReader):
1235
	def __init__(self, file):
1236
		super().__init__(file)
1237
		self.in_string = None
1238
		self.should_recognize_strings = True
1239
 
1240
	def step(self):
1241
		c = super().step()
1242
		if self.should_recognize_strings and (c == '"' or c == "'"):
1243
			# If just now we was at the double or single quotation mark
1244
			# and we aren't in a string yet
1245
			# then say "we are in a string openned with this quotation mark now"
1246
			if self.in_string == None:
1247
				self.in_string = c
1248
			# If just now we was at the double or single quotation mark
1249
			# and we are in the string entered with the same quotation mark
1250
			# then say "we aren't in a string anymore"
1251
			elif self.in_string == c:
1252
				self.in_string = None
1253
		return c
1254
 
1255
class AsmReaderReadingComments(AsmReaderRecognizingStrings):
1256
	def __init__(self, file):
1257
		super().__init__(file)
1258
		self.status = dict()
1259
		self.status_reset()
1260
		self.comment = ''
1261
 
1262
	def status_reset(self):
1263
		# If the line has non-comment code
1264
		self.status['has_code'] = False
1265
		# If the line has a comment at the end
1266
		self.status['has_comment'] = False
1267
		# Let it recognize strings further, we are definitely out of a comment
1268
		self.should_recognize_strings = True
1269
 
1270
	def status_set_has_comment(self):
1271
		self.status['has_comment'] = True
1272
		# Don't let it recognize strings cause we are in a comment now
1273
		self.should_recognize_strings = False
1274
 
1275
	def status_set_has_code(self):
1276
		self.status['has_code'] = True
1277
 
1278
	def status_has_comment(self):
1279
		return self.status['has_comment']
1280
 
1281
	def status_has_code(self):
1282
		return self.status['has_code']
1283
 
1284
	def update_status(self):
1285
		# If we aren't in a comment and we aren't in a string - say we are now in a comment if ';' met
1286
		if not self.status_has_comment() and not self.in_string and self.curr() == ';':
1287
			self.status_set_has_comment()
1288
		# Else if we are in a comment - collect the comment
1289
		elif self.status_has_comment():
1290
			self.comment += self.curr()
1291
		# Else if there's some non-whitespace character out of a comment
1292
		# then the line has code
1293
		elif not self.status_has_comment() and not self.curr().isspace():
1294
			self.status_set_has_code()
1295
 
1296
	def step(self):
1297
		# Get to the next character
1298
		c = super().step()
1299
		# Update status of the line according to the next character
1300
		self.update_status()
1301
		return c
1302
 
1303
	def nextline(self):
1304
		super().nextline()
1305
		# If the line we leave was not a comment-only line
1306
		# then forget the collected comment
1307
		# Otherwise the collected comment should be complemented by comment from next line in step()
1308
		if self.status_has_code():
1309
			self.comment = ''
1310
		# Reset the line status (now it's the status of the new line)
1311
		self.status_reset()
1312
		# Set new status for this line according to the first character in the line
1313
		self.update_status()
1314
 
1315
	def get_comment(self):
1316
		return self.comment
1317
 
1318
class AsmReader(AsmReaderReadingComments):
1319
	def __init__(self, file):
1320
		super().__init__(file)
1321
 
1322
created_files = []
1323
 
1324
class AsmElement:
1325
	def __init__(self, location, name, comment):
1326
		self.location = location
1327
		self.file = self.location.split(':')[0].replace('\\', '/')
1328
		self.line = self.location.split(':')[1]
8855 Boppan 1329
		self.name = name
8957 Boppan 1330
		self.comment = comment
1331
 
1332
	def dump(self):
1333
		print(f"{self.comment}")
1334
		print(f"{self.location}: {self.name}")
1335
 
1336
	def emit(self, dest, doxycomment = '', declaration = ''):
1337
		global warnings
1338
		# Redefine default declaration
1339
		if declaration == '':
1340
			declaration = f'#define {self.name}'
1341
		# Check doxycomment
1342
		if not doxycomment.endswith('\n'):
1343
			doxycomment += '\n'
1344
		if doxycomment.split('@brief ')[1][0].islower():
1345
			warnings += f"{self.location}: Brief comment starting from lowercase\n"
1346
		# Build contents to emit
1347
		contents = ''
1348
		contents += '/**\n'
1349
		contents += doxycomment
1350
		contents += (f"@par Source\n" +
1351
		             f"{self.file}:{self.line}\n")
1352
		contents += '*/\n'
1353
		contents += declaration
1354
		contents += '\n\n'
1355
		# Get path to file to emit this
1356
		full_path = dest + '/' + self.file
1357
		# Remove the file on first access if it was created by previous generation
1358
		if full_path not in created_files:
1359
			if os.path.isfile(full_path):
1360
				os.remove(full_path)
1361
			created_files.append(full_path)
1362
		# Only remove the file on 'clean_generated_stuff' flag (removed above, just return)
1363
		if clean_generated_stuff:
1364
			return
1365
		# Create directories need for the file
1366
		os.makedirs(os.path.dirname(full_path), exist_ok=True)
1367
		f = open(full_path, "a")
1368
		contents = ''.join([i if ord(i) < 128 else '?' for i in contents])
1369
		f.write(contents)
1370
		f.close()
1371
 
1372
class AsmVariable(AsmElement):
1373
	def __init__(self, location, name, comment, type, init):
1374
		super().__init__(location, name, comment)
8855 Boppan 1375
		self.type = type
1376
		self.init = init
1377
 
8957 Boppan 1378
	def dump(self):
1379
		super().dump()
1380
		print(f"Variable")
8855 Boppan 1381
 
8957 Boppan 1382
	def emit(self, dest):
1383
		# Build doxycomment specific for the variable
1384
		doxycomment = ''
1385
		doxycomment += self.comment
1386
		if '@brief' not in doxycomment:
1387
			doxycomment = '@brief ' + doxycomment
1388
		doxycomment += (f"@par Initial value\n" +
1389
		                f"{self.init}\n")
1390
		# Build the declaration
1391
		name = self.name.replace(".", "_")
1392
		var_type = self.type.replace(".", "_")
1393
		declaration = f"{var_type} {name};"
1394
		# Emit this
1395
		super().emit(dest, doxycomment, declaration)
8855 Boppan 1396
 
8957 Boppan 1397
class AsmFunction(AsmElement):
1398
	def __init__(self, location, name, comment):
1399
		super().__init__(location, name, comment)
8855 Boppan 1400
 
8957 Boppan 1401
	def dump(self):
1402
		super().dump()
1403
		print(f"Function")
8855 Boppan 1404
 
8957 Boppan 1405
	def emit(self, dest):
1406
		# Build doxycomment specific for the variable
1407
		doxycomment = ''
1408
		doxycomment += self.comment
1409
		if '@brief' not in doxycomment:
1410
			doxycomment = '@brief ' + doxycomment
1411
		# Build the declaration
1412
		name = self.name.replace(".", "_")
1413
		declaration = f"void {name}();"
1414
		# Emit this
1415
		super().emit(dest, doxycomment, declaration)
8855 Boppan 1416
 
8957 Boppan 1417
class AsmLabel(AsmElement):
1418
	def __init__(self, location, name, comment):
1419
		super().__init__(location, name, comment)
8855 Boppan 1420
 
8957 Boppan 1421
	def dump(self):
1422
		super().dump()
1423
		print(f"Label")
8855 Boppan 1424
 
8957 Boppan 1425
	def emit(self, dest):
1426
		# Build doxycomment specific for the variable
1427
		doxycomment = ''
1428
		doxycomment += self.comment
1429
		if '@brief' not in doxycomment:
1430
			doxycomment = '@brief ' + doxycomment
1431
		# Build the declaration
1432
		name = self.name.replace(".", "_")
1433
		declaration = f"label {name};"
1434
		# Emit this
1435
		super().emit(dest, doxycomment, declaration)
8855 Boppan 1436
 
8957 Boppan 1437
class AsmMacro(AsmElement):
1438
	def __init__(self, location, name, comment, args):
1439
		super().__init__(location, name, comment)
1440
		self.args = args
8855 Boppan 1441
 
8957 Boppan 1442
	def dump(self):
1443
		super().dump()
1444
		print(f"Macro")
1445
		print(f"Parameters: {self.args}")
8855 Boppan 1446
 
8957 Boppan 1447
	def emit(self, dest):
1448
		# Construct arg list without '['s, ']'s and '*'s
1449
		args = [arg for arg in self.args if arg not in "[]*"]
1450
		# Construct C-like arg list
1451
		arg_list = ""
1452
		if len(args) > 0:
1453
			arg_list += '('
1454
			argc = 0
1455
			for arg in args:
1456
				if argc != 0:
1457
					arg_list += ", "
1458
				arg_list += arg
1459
				argc += 1
1460
			arg_list += ')'
1461
		# Build doxycomment
1462
		doxycomment = ''
1463
		doxycomment += self.comment
1464
		if '@brief' not in doxycomment:
1465
			doxycomment = '@brief ' + doxycomment
1466
		# Build declaration
1467
		declaration = f"#define {self.name}{arg_list}"
1468
		# Emit this
1469
		super().emit(dest, doxycomment, declaration)
8855 Boppan 1470
 
8957 Boppan 1471
class AsmStruct(AsmElement):
1472
	def __init__(self, location, name, comment, members):
1473
		super().__init__(location, name, comment)
1474
		self.members = members
8855 Boppan 1475
 
8957 Boppan 1476
	def dump(self):
1477
		super().dump()
1478
		print(f"Struct")
8855 Boppan 1479
 
8957 Boppan 1480
	def emit(self, dest):
1481
		# Build doxycomment
1482
		doxycomment = ''
1483
		doxycomment += self.comment
1484
		if '@brief' not in doxycomment:
1485
			doxycomment = '@brief ' + doxycomment
1486
		# Build declaration
1487
		declaration = f"struct {self.name}" + " {};"
1488
		# Emit this
1489
		super().emit(dest, doxycomment, declaration)
8855 Boppan 1490
 
8957 Boppan 1491
class AsmUnion(AsmElement):
1492
	def __init__(self, location, name, comment, members):
1493
		super().__init__(location, name, comment)
1494
		self.members = members
8855 Boppan 1495
 
8957 Boppan 1496
	def dump(self):
1497
		super().dump()
1498
		print(f"Union")
8855 Boppan 1499
 
8957 Boppan 1500
	def emit(self, dest):
1501
		# Build doxycomment
1502
		doxycomment = ''
1503
		doxycomment += self.comment
1504
		if '@brief' not in doxycomment:
1505
			doxycomment = '@brief ' + doxycomment
1506
		# Build declaration
1507
		declaration = f"union {self.name}" + " {};"
1508
		# Emit this
1509
		super().emit(dest, doxycomment, declaration)
8855 Boppan 1510
 
8957 Boppan 1511
class VariableNameIsMacroName:
1512
	def __init__(self, name):
1513
		self.name = name
8855 Boppan 1514
 
8957 Boppan 1515
def is_id(c):
1516
	return c.isprintable() and c not in "+-/*=<>()[]{};:,|&~#`'\" \n\r\t\v"
8855 Boppan 1517
 
8957 Boppan 1518
def is_starts_as_id(s):
1519
	return not s[0].isdigit()
1520
 
1521
def parse_after_macro(r):
1522
	location = r.location()
1523
 
1524
	# Skip spaces after the "macro" keyword
1525
	r.skip_spaces()
8855 Boppan 1526
	# Read macro name
1527
	name = ""
8957 Boppan 1528
	while is_id(r.curr()) or r.curr() == '#':
1529
		name += r.step()
8855 Boppan 1530
	# Skip spaces after macro name
8957 Boppan 1531
	r.skip_spaces()
8855 Boppan 1532
	# Find all arguments
1533
	args = []
1534
	arg = ''
8957 Boppan 1535
	while r.curr() and r.curr() != ';' and r.curr() != '{':
8855 Boppan 1536
		# Collect identifier
8957 Boppan 1537
		if is_id(r.curr()):
1538
			arg += r.step()
8855 Boppan 1539
		# Save the collected identifier
8957 Boppan 1540
		elif r.curr() == ',':
8855 Boppan 1541
			args.append(arg)
1542
			arg = ''
8957 Boppan 1543
			r.step()
8855 Boppan 1544
		# Just push the '['
8957 Boppan 1545
		elif r.curr() == '[':
1546
			args.append(r.step())
8855 Boppan 1547
		# Just push the identifier and get ']' ready to be pushed on next comma
8957 Boppan 1548
		elif r.curr() == ']':
8855 Boppan 1549
			args.append(arg)
8957 Boppan 1550
			arg = r.step()
8855 Boppan 1551
		# Just push the identifier and get '*' ready to be pushed on next comma
8957 Boppan 1552
		elif r.curr() == '*':
8855 Boppan 1553
			args.append(arg)
8957 Boppan 1554
			arg = r.step()
8855 Boppan 1555
		# Just skip whitespaces
8957 Boppan 1556
		elif r.curr().isspace():
1557
			r.step()
8855 Boppan 1558
		# Something unexpected
1559
		else:
8957 Boppan 1560
			raise Exception(f"Unexpected symbol '{r.curr()}' at index #{r.i} " +
1561
			                f"in the macro declaration at {location} " +
1562
			                f"(line: {r.lines[r.line_idx]})\n''")
1563
	# Append the last argument
8855 Boppan 1564
	if arg != '':
1565
		args.append(arg)
8957 Boppan 1566
	# Skip t spaces after the argument list
1567
	r.skip_spaces()
1568
	# Get a comment if it is: read till the end of the line and get the comment from the reader
1569
	while r.curr() != '':
1570
		r.step()
1571
	comment = r.comment
8855 Boppan 1572
	# Find end of the macro
8957 Boppan 1573
	prev = ''
1574
	while True:
1575
		if r.curr() == '}' and prev != '\\':
1576
			break
1577
		elif r.curr() == '':
1578
			prev = ''
1579
			r.nextline()
1580
			continue
1581
		prev = r.step()
8855 Boppan 1582
	# Build the output
8957 Boppan 1583
	return AsmMacro(location, name, comment, args)
8855 Boppan 1584
 
8957 Boppan 1585
def parse_variable(r, first_word = None):
1586
	global warnings
1587
	location = r.location()
8825 Boppan 1588
 
8957 Boppan 1589
	# Skip spaces before variable name
1590
	r.skip_spaces()
1591
	# Get variable name
1592
	name = ""
1593
	# Read it if it was not supplied
1594
	if first_word == None:
1595
		while is_id(r.curr()):
1596
			name += r.step()
1597
	# Or use the supplied one instead
1598
	else:
1599
		name = first_word
1600
	# Check the name
1601
	# If it's 0 len, that means threr's something else than an identifier at the beginning
1602
	if len(name) == 0:
1603
		return None
1604
	# If it starts from digit or othervice illegally it's illegal
1605
	if not is_starts_as_id(name):
1606
		return None
1607
	# If it's a keyword, that's not a variable declaration
1608
	if name in keywords:
1609
		return None
1610
	# If it's a macro name, that's not a variable declaration
1611
	if name in macro_names:
1612
		return VariableNameIsMacroName(name)
1613
	# If it's a datatype or a structure name that's not a variable declaration: that's just a data
1614
	# don't document just a data for now
1615
	if name in struct_names or name in fasm_types:
1616
		return None
1617
	# Skip spaces before type name
1618
	r.skip_spaces()
1619
	# Read type name
1620
	var_type = ""
1621
	while is_id(r.curr()):
1622
		var_type += r.step()
1623
	# Check the type name
1624
	if len(var_type) == 0:
1625
		# If there's no type identifier after the name
1626
		# maybe the name is something meaningful for the next parser
1627
		# return it
1628
		return name
1629
	# If it starts from digit or othervice illegally it's illegal
1630
	if not is_starts_as_id(var_type):
1631
		return None
1632
	# If it's a keyword, that's not a variable declaration
1633
	# return the two words of the lexical structure
1634
	if var_type in keywords:
1635
		return (name, var_type)
1636
	# Skip spaces before the value
1637
	r.skip_spaces()
1638
	# Read the value until the comment or end of the line
1639
	value = ""
1640
	while r.curr() != ';' and r.curr() != '' and r.curr() != '\n':
1641
		value += r.step()
1642
	# Skip spaces after the value
1643
	r.skip_spaces()
1644
	# Read a comment if any
1645
	comment = ''
1646
	if r.curr() == ';':
1647
		# Skip the ';'
1648
		r.step()
1649
		# Read the comment
1650
		while r.curr() != '':
1651
			comment += r.step()
1652
	# Postprocess type
1653
	return AsmVariable(location, name, r.comment, var_type, value)
8825 Boppan 1654
 
8957 Boppan 1655
def parse_after_struct(r, as_union = True):
1656
	global warnings
1657
	location = r.location()
8825 Boppan 1658
 
8957 Boppan 1659
	# Skip spaces after "struct" keyword
1660
	r.skip_spaces()
1661
	# Read struct name
1662
	name = ""
1663
	while is_id(r.curr()):
1664
		name += r.step()
1665
	# Read till end of the line and get the comment from the reader
1666
	while r.curr() != '':
1667
		r.step()
1668
	comment = r.comment
1669
	# Get to the next line to parse struct members
1670
	r.nextline()
1671
	# Parse struct members
1672
	members = []
1673
	while True:
1674
		r.skip_spaces()
1675
		var = parse_variable(r)
1676
		if type(var) == AsmVariable:
1677
			members.append(var)
1678
		elif type(var) == str:
1679
			if var == 'union':
1680
				# Parse the union as a struct
1681
				union = parse_after_struct(r, as_union = True)
1682
				members.append(union)
1683
				# Skip the ends of the union
1684
				r.nextline()
1685
			elif r.curr() == ':':
1686
				warnings += f"{r.location()}: Skept the label in the struct\n"
1687
			else:
1688
				raise Exception(f"Garbage in struct member at {location} (got '{var}' identifier)")
1689
		elif type(var) == VariableNameIsMacroName:
1690
			if var.name == 'ends':
1691
				break
1692
		r.nextline()
1693
	# Return the result
1694
	if as_union:
1695
		return AsmStruct(location, name, comment, members)
1696
	else:
1697
		return AsmUnion(location, name, comment, members)
8825 Boppan 1698
 
8957 Boppan 1699
def get_declarations(asm_file_contents, asm_file_name):
1700
	cwd = os.path.abspath(os.path.dirname(sys.argv[0]))
1701
	asm_file_name = os.path.realpath(asm_file_name)
1702
	asm_file_name = asm_file_name[len(cwd) + 1:]
8825 Boppan 1703
 
8957 Boppan 1704
	r = AsmReader(asm_file_name)
8825 Boppan 1705
 
8957 Boppan 1706
	while not r.no_lines():
1707
		# Skip leading spaces
1708
		r.skip_spaces()
1709
		# Skip the line if it's starting with a comment
1710
		if r.curr() == ';':
1711
			r.nextline()
8825 Boppan 1712
			continue
8957 Boppan 1713
		# Get first word
1714
		first_word = ""
1715
		while is_id(r.curr()):
1716
			first_word += r.step()
1717
		# Match macro declaration
1718
		if first_word == "macro":
1719
			macro = parse_after_macro(r)
1720
			elements.append(macro)
1721
			macro_names.append(macro.name)
1722
		# Match structure declaration
1723
		elif first_word == "struct":
1724
			struct = parse_after_struct(r)
1725
			elements.append(struct)
1726
			struct_names.append(struct.name)
1727
		# Match function definition
1728
		elif first_word == "proc":
1729
			# Skip spaces after "proc"
1730
			r.skip_spaces()
1731
			# Get proc name
1732
			name = ""
1733
			while is_id(r.curr()):
1734
				name += r.step()
1735
			# Get to the end of the line to get the comment from the reader
1736
			while r.curr() != '':
1737
				r.step()
1738
			comment = r.get_comment()
1739
			# Create the function
1740
			elements.append(AsmFunction(r.location(), name, comment))
1741
		elif first_word == 'format':
1742
			# Skip the format directive
1743
			pass
1744
		elif first_word == 'include':
1745
			# Skip the include directive
1746
			pass
1747
		elif first_word == 'if':
1748
			# Skip the conditional directive
1749
			pass
1750
		elif first_word == 'repeat':
1751
			# Skip the repeat directive
1752
			pass
1753
		elif first_word == 'purge':
1754
			while True:
1755
				# Skip spaces after the 'purge' keyword or after the comma what separated the previous macro name
1756
				r.skip_spaces()
1757
				# Get the purged macro name
1758
				name = ''
1759
				while is_id(r.curr()):
1760
					name += r.step()
1761
				# Remove the purged macro from the macro names list
1762
				try:
1763
					macro_names.remove(name)
1764
				except:
1765
					pass
1766
				# Skip spaces after the name
1767
				r.skip_spaces()
1768
				# If it's comma (',') after then that's not the last purged macro, continue purging
1769
				if r.curr() == ',':
1770
					r.step()
1771
					continue
1772
				# Here we purged all the macros should be purged
1773
				break
1774
		# Match label or a variable
1775
		elif len(first_word) != 0:
1776
			# Skip spaces after the identifier
1777
			r.skip_spaces()
1778
			# Match a variable
1779
			var = parse_variable(r, first_word)
1780
			if type(var) == AsmVariable:
1781
				elements.append(var)
1782
			# If it wasn't a variable but there was an identifier
1783
			# Maybe that's a label and the identifier is the label name
1784
			# The parse_variable returns the first found or supplied identifier
1785
			# In this case it returns the first_word which is supplied
1786
			# If it didn't match a type identifier after the word
1787
			elif type(var) == str:
1788
				name = var
1789
				# Match label beginning (':' after name)
1790
				if r.curr() == ':':
1791
					# Get to the end of the line and get the coment from the reader
1792
					while r.curr() != '':
1793
						r.step()
1794
					comment = r.comment
1795
					# Only handle non-local labels
1796
					if name[0] != '.' and name != "@@" and name != "$Revision":
1797
						elements.append(AsmLabel(r.location(), name, comment))
1798
				elif r.curr() == '=':
1799
					# Add the equated constant (name = value) to equated constants list
1800
					equated_constant_names.append(first_word)
1801
			elif type(var) == tuple:
1802
				(word_one, word_two) = var
1803
				if word_two == 'equ':
1804
					# Add the name to equ names list
1805
					equ_names.append(word_one)
1806
		r.nextline()
8825 Boppan 1807
 
8834 Boppan 1808
def handle_file(handled_files, asm_file_name, subdir = "."):
8957 Boppan 1809
	print(f"Parsing {asm_file_name}")
8825 Boppan 1810
	handled_files.append(asm_file_name)
1811
	try:
1812
		asm_file_contents = open(asm_file_name, "r", encoding="utf-8").read()
1813
	except:
1814
		return
8957 Boppan 1815
	include_directive_pattern = re.compile(r'include (["\'])(.*)\1')
1816
	includes = include_directive_pattern.findall(asm_file_contents)
8825 Boppan 1817
	for include in includes:
8957 Boppan 1818
		include = include[1].replace('\\', '/');
8825 Boppan 1819
		full_path = subdir + '/' + include;
1820
		if full_path not in handled_files:
1821
			new_subdir = full_path.rsplit('/', 1)[0]
8834 Boppan 1822
			handle_file(handled_files, full_path, new_subdir)
8957 Boppan 1823
	get_declarations(asm_file_contents, asm_file_name)
8825 Boppan 1824
	return handled_files
1825
 
1826
kernel_files = []
1827
 
8834 Boppan 1828
handle_file(kernel_files, "./kernel.asm");
8825 Boppan 1829
 
8834 Boppan 1830
if dump_symbols:
8957 Boppan 1831
	for asm_element in elements:
1832
		asm_element.dump()
8825 Boppan 1833
 
8834 Boppan 1834
if print_stats:
8957 Boppan 1835
	print("--stats is not nimplmented")
8825 Boppan 1836
 
8834 Boppan 1837
print(f"Writing doumented sources to {doxygen_src_path}")
1838
 
8957 Boppan 1839
i = 0
1840
for element in elements:
1841
	print(f"[{i + 1}/{len(elements)}] Emitting {element.name} from {element.location}")
1842
	element.emit(doxygen_src_path)
8834 Boppan 1843
	i += 1
8855 Boppan 1844
 
1845
if enable_warnings:
1846
	open('asmxygen.txt', "w", encoding = "utf-8").write(warnings)