1166124Srafan/****************************************************************************
2166124Srafan * Copyright (c) 1998,2006 Free Software Foundation, Inc.                   *
3166124Srafan *                                                                          *
4166124Srafan * Permission is hereby granted, free of charge, to any person obtaining a  *
5166124Srafan * copy of this software and associated documentation files (the            *
6166124Srafan * "Software"), to deal in the Software without restriction, including      *
7166124Srafan * without limitation the rights to use, copy, modify, merge, publish,      *
8166124Srafan * distribute, distribute with modifications, sublicense, and/or sell       *
9166124Srafan * copies of the Software, and to permit persons to whom the Software is    *
10166124Srafan * furnished to do so, subject to the following conditions:                 *
11166124Srafan *                                                                          *
12166124Srafan * The above copyright notice and this permission notice shall be included  *
13166124Srafan * in all copies or substantial portions of the Software.                   *
14166124Srafan *                                                                          *
15166124Srafan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16166124Srafan * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17166124Srafan * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18166124Srafan * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19166124Srafan * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20166124Srafan * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21166124Srafan * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22166124Srafan *                                                                          *
23166124Srafan * Except as contained in this notice, the name(s) of the above copyright   *
24166124Srafan * holders shall not be used in advertising or otherwise to promote the     *
25166124Srafan * sale, use or other dealings in this Software without prior written       *
26166124Srafan * authorization.                                                           *
27166124Srafan ****************************************************************************/
28166124Srafan
2950276Speter/*
30166124Srafan * $Id: makedef.cmd,v 1.5 2006/04/22 23:14:50 tom Exp $
3150276Speter *
3250276Speter * Author:  Juan Jose Garcia Ripoll <worm@arrakis.es>.
3350276Speter * Webpage: http://www.arrakis.es/~worm/
3450276Speter *
3550276Speter * makedef.cmd - update a DLL export list using a newly created library file
3650276Speter *		 in a.out format, plus an old .DEF file.
3750276Speter *
3850276Speter * standard output gets a sorted list with all entrypoints with entrycodes.
3950276Speter * This list, plus a few .def sentences (LIBRARY, DESCRIPTION and EXPORT)
4050276Speter * is used to build a new .def file.
4150276Speter *
4250276Speter * `_nc_*' symbols are ignored.
4350276Speter *
4450276Speter * returns 1 when the old def_file is corrupted -- that is, export items are
4550276Speter * not properly formatted.
4650276Speter *
4750276Speter * returns 0 if everything went OK.
4850276Speter */
4950276Speter
5050276Speterparse arg lib_file def_file
5150276Speter
5250276Speterlib_file = translate(lib_file,'\','/')
5350276Speterdef_file = translate(def_file,'\','/')
5450276Speter
5550276Spetercall CleanQueue
5650276Speter
5750276Speter/*
5850276Speter * `codes' is the stem that links a code to every symbol
5950276Speter * `names' is the stem where symbols are stored sequentially
6050276Speter * `last' is the index of the last symbol defined
6150276Speter */
6250276Speterlast   = 0
6350276Speterused.  = 0
6450276Spetercodes. = 0
6550276Speternames. = ''
6650276Speter
6750276Spetertmp_name = 'foo.tmp'
6850276Speter
6950276Speter/*
7050276Speter * This sed expression cleans empty lines, comments and special .DEF
7150276Speter * commands, such as LIBRARY..., EXPORTS..., etc
7250276Speter */
7350276Spetertidy_up  = '"/^[A-Z]/d;s/[ 	][ 	]*/ /g;s/;.*$//g;s/^[ ]*//g;/^[ ]*$/d"'
7450276Speter
7550276Speter/*
7650276Speter * First we find all public symbols (functions and variables). Next we
7750276Speter * concatenate this list with the old one, sorting it and wiping out
7850276Speter * all unused data (comments, DLL directives, blanks, etc). All this
7950276Speter * information is pushed into a REXX private list with the RXQUEUE
8050276Speter * utility program.
8150276Speter */
8250276Speter'@echo off'
8350276Speter'emxexp -u' lib_file '>' tmp_name
8450276Speter'cat' tmp_name def_file '| sed' tidy_up '| sort > foo2.tmp'
8550276Speter'type foo2.tmp | rxqueue'
8650276Speter'del' tmp_name '1>NUL'
8750276Speter
8850276Speter/*
8950276Speter * This loop runs over the queue items
9050276Speter */
9150276Speterdo while queued() > 0
9250276Speter   /*
9350276Speter    * We retrieve the symbol name (NEW_NAME) and its number (NEW_NUMBER)
9450276Speter    * When the line comes from `emximp's output, there's no number, so
9550276Speter    * we assign it the special value 0.
9650276Speter    */
9750276Speter   parse pull new_symbol '@'new_code rest
9850276Speter   if Left(new_symbol,1) = '"' then
9950276Speter      parse var new_symbol '"' new_name '"' rest
10050276Speter   else
10150276Speter      do
10250276Speter      echo 'Symbol 'new_symbol' was not quoted'
10350276Speter      new_name = new_symbol
10450276Speter      end
10550276Speter
10650276Speter   if new_code = '' then
10750276Speter      new_code = 0
10850276Speter   /*
10950276Speter    * Here, one would place all smart checks that would kill unused symbols.
11050276Speter    * However, export tables are not that big, so why bothering?
11150276Speter   if Left(new_name,4) = '_nc_' then
11250276Speter      iterate
11350276Speter    */
11450276Speter   /*
11550276Speter    * The algorithm:
11650276Speter    *	IF (this is the 2nd time the symbol appears) THEN
11750276Speter    *		(this symbol comes from a .DEF file)
11850276Speter    *		it has a valid code that we store
11950276Speter    *		we mark that code as used
12050276Speter    *   ELIF (it has no number) THEN
12150276Speter    *		(it's a new symbol)
12250276Speter    *		we increase the counter of defined symbols
12350276Speter    *		we assign it the special number 0
12450276Speter    *		(later on it'll be assigned an unused export code)
12550276Speter    *   ELSE
12650276Speter    *		this symbol was in the old DLL and it's no longer
12750276Speter    *		here, so we skip it.
12850276Speter    */
12950276Speter   select
13050276Speter      when new_name = '' then
13150276Speter         'echo Warning: empty symbol found 1>&2'
13250276Speter      when names.last = new_name then
13350276Speter         do
13450276Speter         codes.last = new_code
13550276Speter         used.new_code = 1
13650276Speter         end
13750276Speter      when new_code = 0 then
13850276Speter         do
13950276Speter         last = last + 1
14050276Speter         names.last = new_name
14150276Speter         codes.last = 0
14250276Speter         end
14350276Speter   otherwise
14450276Speter      'echo Warning: symbol "'new_name'" has disappeared 1>&2'
14550276Speter   end /* select */
14650276Speterend /* do while queued() */
14750276Speter
14850276Speter/*
14950276Speter * Finally we scan the stem, writing out all symbols with export codes.
15050276Speter * Those that did not have a valid one (just 0) are assigned a new one.
15150276Speter */
15250276Speternew_code = 1
15350276Speterinx = 1
15450276Speterdo while inx <= last
15550276Speter   if codes.inx = 0 then
15650276Speter      do
15750276Speter      do while used.new_code \= 0
15850276Speter         new_code = new_code + 1
15950276Speter      end
16050276Speter      codes.inx = new_code
16150276Speter      used.new_code = 1
16250276Speter      end
16350276Speter   say '	"'names.inx'"	@'codes.inx'	NONAME'
16450276Speter   inx = inx + 1
16550276Speterend
16650276Speter'del foo2.tmp 1>NUL'
16750276Speterexit 0
16850276Speter
16950276Speter/*
17050276Speter * Cleans the REXX queue by pulling and forgetting every line.
17150276Speter * This is needed, at least, when `makedef.cmd' starts, because an aborted
17250276Speter * REXX program might have left some rubbish in.
17350276Speter */
17450276SpeterCleanQueue: procedure
17550276Speter   do while queued() > 0
17650276Speter      parse pull foo
17750276Speter   end
17850276Speterreturn
17950276Speter
180