Git init
[external/mawk.git] / msdos / examples / winexe.awk
1 # Ben Myers <0003571400@mcimail.com>
2
3 # Sum up segment sizes of all Windows EXEs in current directory
4 # requires DOS 5.0 and Borland TDUMP
5 # run with
6 #       awk -fwinexe.awk work1
7 # where work1 is a work file
8 # You must have at least one filename as an arg, else awk will want to read
9 # from con:, hence the requirement for work1
10 BEGIN {
11 # redirection done by shelled command
12 system("del workfile.$%$") # Will probably cause a File Not Found message
13 # Generate a list of EXEs
14 system("dir *.exe /b > workfile.$%$")
15 while (getline < "workfile.$%$" > 0) {
16 # TDUMP keeps on piping to the workfile
17 system("tdump " $1 ">> " ARGV[1])
18 }
19 module_name = "" # initialize
20 # Now read workfile back, processing lines that:
21 # 1. contain EXE file name
22 # 2. contain segment type
23 # Print EXE name and stats for each segment type processed
24 # When there is a new EXE name, print summary for EXE just processed
25 j = 1
26 while (getline < ARGV[1] > 0) {
27 # module name
28 if($1 == "Display" && $2 == "of" && $3 == "File") {
29 # Print program summary for all but last program
30 if(module_name != "") { Print_Summary() }
31 otcount = 0 # text segment counter
32 odcount = 0 # data segment counter
33 otsize = 0  # text size accumulator
34 odsize = 0  # data size accumulator
35 module_name = $4 }
36 # File Size
37 if($1 == "DOS" && $2 == "File" && $3 == "Size") {
38 # 6+ digit file size with leading left paren
39 DOS_Size = substr($5,2,7)
40 # file size < 6 digits
41 if(DOS_Size == 0 || DOS_Size == "") { DOS_Size = $6 }
42 }
43 # CODE segment
44 if($1 == "Segment" && $2 == "Type:" && $3 =="CODE") {
45 decval = hexdec(substr($7,1,4))
46 otsize += decval
47 # printf ("%12s CODE %4s %7u\n", module_name, $7, decval)
48 otcount++ }
49 # DATA segment
50 if($1 == "Segment" && $2 == "Type:" && $3 =="DATA") {
51 decval = hexdec(substr($7,1,4))
52 odsize += decval
53 # printf ("%12s DATA %4s %7u\n", module_name, $7, decval)
54 odcount++ }
55 } # while
56 } # end of BEGIN section
57 # no main loop at all!
58 END {
59 # print record for last program
60 Print_Summary()
61 # delete work files
62 system("del "ARGV[1])
63 system("del workfile.$%$")
64 }  # end of END section
65
66 # No scanf in awk, so convert hex string x to decimal the hard way
67 function hexdec (x) {
68 result = 0
69 for (i=1; i<=length(x); i++) {
70 thechar = substr(x,i,1)
71 # digits 0-9 and lower case hex produced by TDUMP
72 # use brute force
73 if (thechar == "0") {result = result*16}
74 if (thechar == "1") {result = result*16 + 1}
75 if (thechar == "2") {result = result*16 + 2}
76 if (thechar == "3") {result = result*16 + 3}
77 if (thechar == "4") {result = result*16 + 4}
78 if (thechar == "5") {result = result*16 + 5}
79 if (thechar == "6") {result = result*16 + 6}
80 if (thechar == "7") {result = result*16 + 7}
81 if (thechar == "8") {result = result*16 + 8}
82 if (thechar == "9") {result = result*16 + 9}
83 if (thechar == "a") {result = result*16 + 10}
84 if (thechar == "b") {result = result*16 + 11}
85 if (thechar == "c") {result = result*16 + 12}
86 if (thechar == "d") {result = result*16 + 13}
87 if (thechar == "e") {result = result*16 + 14}
88 if (thechar == "f") {result = result*16 + 15}
89 if (thechar == "A") {result = result*16 + 10}
90 if (thechar == "B") {result = result*16 + 11}
91 if (thechar == "C") {result = result*16 + 12}
92 if (thechar == "D") {result = result*16 + 13}
93 if (thechar == "E") {result = result*16 + 14}
94 if (thechar == "F") {result = result*16 + 15}
95 } # for (i=1;i<length(x);i++)
96 return result
97 } # function hexdec (x)
98
99 function Print_Summary () {
100 # zero segment counts mean non-Windows EXE, so don't print
101 if (otcount+otcount != 0) {
102 printf ("%12s - %10.0f bytes\n", module_name, DOS_Size)
103 printf ("%5.0f TEXT segments with %10.0f bytes\n", otcount, otsize)
104 printf ("%5.0f DATA segments with %10.0f bytes\n", odcount, odsize)
105 }
106 }