14a1a9510SRong-En Fan/**************************************************************************** 2*21817992SBaptiste Daroussin * Copyright 2020,2021 Thomas E. Dickey * 3e1865124SBaptiste Daroussin * Copyright 1998,2006 Free Software Foundation, Inc. * 44a1a9510SRong-En Fan * * 54a1a9510SRong-En Fan * Permission is hereby granted, free of charge, to any person obtaining a * 64a1a9510SRong-En Fan * copy of this software and associated documentation files (the * 74a1a9510SRong-En Fan * "Software"), to deal in the Software without restriction, including * 84a1a9510SRong-En Fan * without limitation the rights to use, copy, modify, merge, publish, * 94a1a9510SRong-En Fan * distribute, distribute with modifications, sublicense, and/or sell * 104a1a9510SRong-En Fan * copies of the Software, and to permit persons to whom the Software is * 114a1a9510SRong-En Fan * furnished to do so, subject to the following conditions: * 124a1a9510SRong-En Fan * * 134a1a9510SRong-En Fan * The above copyright notice and this permission notice shall be included * 144a1a9510SRong-En Fan * in all copies or substantial portions of the Software. * 154a1a9510SRong-En Fan * * 164a1a9510SRong-En Fan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 174a1a9510SRong-En Fan * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 184a1a9510SRong-En Fan * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 194a1a9510SRong-En Fan * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 204a1a9510SRong-En Fan * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 214a1a9510SRong-En Fan * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 224a1a9510SRong-En Fan * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 234a1a9510SRong-En Fan * * 244a1a9510SRong-En Fan * Except as contained in this notice, the name(s) of the above copyright * 254a1a9510SRong-En Fan * holders shall not be used in advertising or otherwise to promote the * 264a1a9510SRong-En Fan * sale, use or other dealings in this Software without prior written * 274a1a9510SRong-En Fan * authorization. * 284a1a9510SRong-En Fan ****************************************************************************/ 294a1a9510SRong-En Fan 300e3d5408SPeter Wemm/* 31*21817992SBaptiste Daroussin * $Id: makedef.cmd,v 1.7 2021/09/04 10:52:55 tom Exp $ 320e3d5408SPeter Wemm * 330e3d5408SPeter Wemm * Author: Juan Jose Garcia Ripoll <worm@arrakis.es>. 340e3d5408SPeter Wemm * Webpage: http://www.arrakis.es/~worm/ 350e3d5408SPeter Wemm * 360e3d5408SPeter Wemm * makedef.cmd - update a DLL export list using a newly created library file 370e3d5408SPeter Wemm * in a.out format, plus an old .DEF file. 380e3d5408SPeter Wemm * 390e3d5408SPeter Wemm * standard output gets a sorted list with all entrypoints with entrycodes. 400e3d5408SPeter Wemm * This list, plus a few .def sentences (LIBRARY, DESCRIPTION and EXPORT) 410e3d5408SPeter Wemm * is used to build a new .def file. 420e3d5408SPeter Wemm * 430e3d5408SPeter Wemm * `_nc_*' symbols are ignored. 440e3d5408SPeter Wemm * 450e3d5408SPeter Wemm * returns 1 when the old def_file is corrupted -- that is, export items are 460e3d5408SPeter Wemm * not properly formatted. 470e3d5408SPeter Wemm * 480e3d5408SPeter Wemm * returns 0 if everything went OK. 490e3d5408SPeter Wemm */ 500e3d5408SPeter Wemm 510e3d5408SPeter Wemmparse arg lib_file def_file 520e3d5408SPeter Wemm 530e3d5408SPeter Wemmlib_file = translate(lib_file,'\','/') 540e3d5408SPeter Wemmdef_file = translate(def_file,'\','/') 550e3d5408SPeter Wemm 560e3d5408SPeter Wemmcall CleanQueue 570e3d5408SPeter Wemm 580e3d5408SPeter Wemm/* 590e3d5408SPeter Wemm * `codes' is the stem that links a code to every symbol 600e3d5408SPeter Wemm * `names' is the stem where symbols are stored sequentially 610e3d5408SPeter Wemm * `last' is the index of the last symbol defined 620e3d5408SPeter Wemm */ 630e3d5408SPeter Wemmlast = 0 640e3d5408SPeter Wemmused. = 0 650e3d5408SPeter Wemmcodes. = 0 660e3d5408SPeter Wemmnames. = '' 670e3d5408SPeter Wemm 680e3d5408SPeter Wemmtmp_name = 'foo.tmp' 690e3d5408SPeter Wemm 700e3d5408SPeter Wemm/* 710e3d5408SPeter Wemm * This sed expression cleans empty lines, comments and special .DEF 720e3d5408SPeter Wemm * commands, such as LIBRARY..., EXPORTS..., etc 730e3d5408SPeter Wemm */ 740e3d5408SPeter Wemmtidy_up = '"/^[A-Z]/d;s/[ ][ ]*/ /g;s/;.*$//g;s/^[ ]*//g;/^[ ]*$/d"' 750e3d5408SPeter Wemm 760e3d5408SPeter Wemm/* 770e3d5408SPeter Wemm * First we find all public symbols (functions and variables). Next we 780e3d5408SPeter Wemm * concatenate this list with the old one, sorting it and wiping out 790e3d5408SPeter Wemm * all unused data (comments, DLL directives, blanks, etc). All this 800e3d5408SPeter Wemm * information is pushed into a REXX private list with the RXQUEUE 810e3d5408SPeter Wemm * utility program. 820e3d5408SPeter Wemm */ 830e3d5408SPeter Wemm'@echo off' 840e3d5408SPeter Wemm'emxexp -u' lib_file '>' tmp_name 850e3d5408SPeter Wemm'cat' tmp_name def_file '| sed' tidy_up '| sort > foo2.tmp' 860e3d5408SPeter Wemm'type foo2.tmp | rxqueue' 870e3d5408SPeter Wemm'del' tmp_name '1>NUL' 880e3d5408SPeter Wemm 890e3d5408SPeter Wemm/* 900e3d5408SPeter Wemm * This loop runs over the queue items 910e3d5408SPeter Wemm */ 920e3d5408SPeter Wemmdo while queued() > 0 930e3d5408SPeter Wemm /* 940e3d5408SPeter Wemm * We retrieve the symbol name (NEW_NAME) and its number (NEW_NUMBER) 950e3d5408SPeter Wemm * When the line comes from `emximp's output, there's no number, so 960e3d5408SPeter Wemm * we assign it the special value 0. 970e3d5408SPeter Wemm */ 980e3d5408SPeter Wemm parse pull new_symbol '@'new_code rest 990e3d5408SPeter Wemm if Left(new_symbol,1) = '"' then 1000e3d5408SPeter Wemm parse var new_symbol '"' new_name '"' rest 1010e3d5408SPeter Wemm else 1020e3d5408SPeter Wemm do 1030e3d5408SPeter Wemm echo 'Symbol 'new_symbol' was not quoted' 1040e3d5408SPeter Wemm new_name = new_symbol 1050e3d5408SPeter Wemm end 1060e3d5408SPeter Wemm 1070e3d5408SPeter Wemm if new_code = '' then 1080e3d5408SPeter Wemm new_code = 0 1090e3d5408SPeter Wemm /* 1100e3d5408SPeter Wemm * Here, one would place all smart checks that would kill unused symbols. 1110e3d5408SPeter Wemm * However, export tables are not that big, so why bothering? 1120e3d5408SPeter Wemm if Left(new_name,4) = '_nc_' then 1130e3d5408SPeter Wemm iterate 1140e3d5408SPeter Wemm */ 1150e3d5408SPeter Wemm /* 1160e3d5408SPeter Wemm * The algorithm: 1170e3d5408SPeter Wemm * IF (this is the 2nd time the symbol appears) THEN 1180e3d5408SPeter Wemm * (this symbol comes from a .DEF file) 1190e3d5408SPeter Wemm * it has a valid code that we store 1200e3d5408SPeter Wemm * we mark that code as used 1210e3d5408SPeter Wemm * ELIF (it has no number) THEN 122*21817992SBaptiste Daroussin * (it is a new symbol) 1230e3d5408SPeter Wemm * we increase the counter of defined symbols 1240e3d5408SPeter Wemm * we assign it the special number 0 1250e3d5408SPeter Wemm * (later on it'll be assigned an unused export code) 1260e3d5408SPeter Wemm * ELSE 127*21817992SBaptiste Daroussin * this symbol was in the old DLL and it is no longer 1280e3d5408SPeter Wemm * here, so we skip it. 1290e3d5408SPeter Wemm */ 1300e3d5408SPeter Wemm select 1310e3d5408SPeter Wemm when new_name = '' then 1320e3d5408SPeter Wemm 'echo Warning: empty symbol found 1>&2' 1330e3d5408SPeter Wemm when names.last = new_name then 1340e3d5408SPeter Wemm do 1350e3d5408SPeter Wemm codes.last = new_code 1360e3d5408SPeter Wemm used.new_code = 1 1370e3d5408SPeter Wemm end 1380e3d5408SPeter Wemm when new_code = 0 then 1390e3d5408SPeter Wemm do 1400e3d5408SPeter Wemm last = last + 1 1410e3d5408SPeter Wemm names.last = new_name 1420e3d5408SPeter Wemm codes.last = 0 1430e3d5408SPeter Wemm end 1440e3d5408SPeter Wemm otherwise 1450e3d5408SPeter Wemm 'echo Warning: symbol "'new_name'" has disappeared 1>&2' 1460e3d5408SPeter Wemm end /* select */ 1470e3d5408SPeter Wemmend /* do while queued() */ 1480e3d5408SPeter Wemm 1490e3d5408SPeter Wemm/* 1500e3d5408SPeter Wemm * Finally we scan the stem, writing out all symbols with export codes. 1510e3d5408SPeter Wemm * Those that did not have a valid one (just 0) are assigned a new one. 1520e3d5408SPeter Wemm */ 1530e3d5408SPeter Wemmnew_code = 1 1540e3d5408SPeter Wemminx = 1 1550e3d5408SPeter Wemmdo while inx <= last 1560e3d5408SPeter Wemm if codes.inx = 0 then 1570e3d5408SPeter Wemm do 1580e3d5408SPeter Wemm do while used.new_code \= 0 1590e3d5408SPeter Wemm new_code = new_code + 1 1600e3d5408SPeter Wemm end 1610e3d5408SPeter Wemm codes.inx = new_code 1620e3d5408SPeter Wemm used.new_code = 1 1630e3d5408SPeter Wemm end 1640e3d5408SPeter Wemm say ' "'names.inx'" @'codes.inx' NONAME' 1650e3d5408SPeter Wemm inx = inx + 1 1660e3d5408SPeter Wemmend 1670e3d5408SPeter Wemm'del foo2.tmp 1>NUL' 1680e3d5408SPeter Wemmexit 0 1690e3d5408SPeter Wemm 1700e3d5408SPeter Wemm/* 1710e3d5408SPeter Wemm * Cleans the REXX queue by pulling and forgetting every line. 1720e3d5408SPeter Wemm * This is needed, at least, when `makedef.cmd' starts, because an aborted 1730e3d5408SPeter Wemm * REXX program might have left some rubbish in. 1740e3d5408SPeter Wemm */ 1750e3d5408SPeter WemmCleanQueue: procedure 1760e3d5408SPeter Wemm do while queued() > 0 1770e3d5408SPeter Wemm parse pull foo 1780e3d5408SPeter Wemm end 1790e3d5408SPeter Wemmreturn 1800e3d5408SPeter Wemm 181