1/*
2 * $Id: makedef.cmd,v 1.4 1998/11/22 03:14:08 tom Exp $
3 *
4 * Author:  Juan Jose Garcia Ripoll <worm@arrakis.es>.
5 * Webpage: http://www.arrakis.es/~worm/
6 *
7 * makedef.cmd - update a DLL export list using a newly created library file
8 *		 in a.out format, plus an old .DEF file.
9 *
10 * standard output gets a sorted list with all entrypoints with entrycodes.
11 * This list, plus a few .def sentences (LIBRARY, DESCRIPTION and EXPORT)
12 * is used to build a new .def file.
13 *
14 * `_nc_*' symbols are ignored.
15 *
16 * returns 1 when the old def_file is corrupted -- that is, export items are
17 * not properly formatted.
18 *
19 * returns 0 if everything went OK.
20 */
21
22parse arg lib_file def_file
23
24lib_file = translate(lib_file,'\','/')
25def_file = translate(def_file,'\','/')
26
27call CleanQueue
28
29/*
30 * `codes' is the stem that links a code to every symbol
31 * `names' is the stem where symbols are stored sequentially
32 * `last' is the index of the last symbol defined
33 */
34last   = 0
35used.  = 0
36codes. = 0
37names. = ''
38
39tmp_name = 'foo.tmp'
40
41/*
42 * This sed expression cleans empty lines, comments and special .DEF
43 * commands, such as LIBRARY..., EXPORTS..., etc
44 */
45tidy_up  = '"/^[A-Z]/d;s/[ 	][ 	]*/ /g;s/;.*$//g;s/^[ ]*//g;/^[ ]*$/d"'
46
47/*
48 * First we find all public symbols (functions and variables). Next we
49 * concatenate this list with the old one, sorting it and wiping out
50 * all unused data (comments, DLL directives, blanks, etc). All this
51 * information is pushed into a REXX private list with the RXQUEUE
52 * utility program.
53 */
54'@echo off'
55'emxexp -u' lib_file '>' tmp_name
56'cat' tmp_name def_file '| sed' tidy_up '| sort > foo2.tmp'
57'type foo2.tmp | rxqueue'
58'del' tmp_name '1>NUL'
59
60/*
61 * This loop runs over the queue items
62 */
63do while queued() > 0
64   /*
65    * We retrieve the symbol name (NEW_NAME) and its number (NEW_NUMBER)
66    * When the line comes from `emximp's output, there's no number, so
67    * we assign it the special value 0.
68    */
69   parse pull new_symbol '@'new_code rest
70   if Left(new_symbol,1) = '"' then
71      parse var new_symbol '"' new_name '"' rest
72   else
73      do
74      echo 'Symbol 'new_symbol' was not quoted'
75      new_name = new_symbol
76      end
77
78   if new_code = '' then
79      new_code = 0
80   /*
81    * Here, one would place all smart checks that would kill unused symbols.
82    * However, export tables are not that big, so why bothering?
83   if Left(new_name,4) = '_nc_' then
84      iterate
85    */
86   /*
87    * The algorithm:
88    *	IF (this is the 2nd time the symbol appears) THEN
89    *		(this symbol comes from a .DEF file)
90    *		it has a valid code that we store
91    *		we mark that code as used
92    *   ELIF (it has no number) THEN
93    *		(it's a new symbol)
94    *		we increase the counter of defined symbols
95    *		we assign it the special number 0
96    *		(later on it'll be assigned an unused export code)
97    *   ELSE
98    *		this symbol was in the old DLL and it's no longer
99    *		here, so we skip it.
100    */
101   select
102      when new_name = '' then
103         'echo Warning: empty symbol found 1>&2'
104      when names.last = new_name then
105         do
106         codes.last = new_code
107         used.new_code = 1
108         end
109      when new_code = 0 then
110         do
111         last = last + 1
112         names.last = new_name
113         codes.last = 0
114         end
115   otherwise
116      'echo Warning: symbol "'new_name'" has disappeared 1>&2'
117   end /* select */
118end /* do while queued() */
119
120/*
121 * Finally we scan the stem, writing out all symbols with export codes.
122 * Those that did not have a valid one (just 0) are assigned a new one.
123 */
124new_code = 1
125inx = 1
126do while inx <= last
127   if codes.inx = 0 then
128      do
129      do while used.new_code \= 0
130         new_code = new_code + 1
131      end
132      codes.inx = new_code
133      used.new_code = 1
134      end
135   say '	"'names.inx'"	@'codes.inx'	NONAME'
136   inx = inx + 1
137end
138'del foo2.tmp 1>NUL'
139exit 0
140
141/*
142 * Cleans the REXX queue by pulling and forgetting every line.
143 * This is needed, at least, when `makedef.cmd' starts, because an aborted
144 * REXX program might have left some rubbish in.
145 */
146CleanQueue: procedure
147   do while queued() > 0
148      parse pull foo
149   end
150return
151
152