source: trunk/tools/impdef/ImpDef.cpp@ 4402

Last change on this file since 4402 was 4402, checked in by bird, 25 years ago

Implemented .Def to WLINK directives/options converter.

File size: 12.2 KB
Line 
1/* $Id: ImpDef.cpp,v 1.4 2000-10-03 05:42:41 bird Exp $ */
2/*
3 * ImpDef - Create export file which use internal names and ordinals.
4 *
5 * Copyright (c) 1999 knut st. osmundsen
6 *
7 */
8
9/*******************************************************************************
10* Header Files *
11*******************************************************************************/
12#include <os2.h>
13#include <stdio.h>
14#include <string.h>
15#include <stdlib.h>
16#include "ImpDef.h"
17#include "kFile.h"
18#include "kFileFormatBase.h"
19#include "kFileDef.h"
20
21
22/*******************************************************************************
23* Internal Functions *
24*******************************************************************************/
25static void syntax(void);
26static long processFile(const char *pszInput, const char *pszOutput, const POPTIONS pOptions);
27static char *generateExportName(const PEXPORTENTRY pExport, char *pszBuffer, const POPTIONS pOptions);
28
29
30/**
31 * Main function.
32 * @returns 0 on success.
33 * @param argc Number of arguments
34 * @param argv Array of arguments
35 */
36int main(int argc, char **argv)
37{
38 int argi;
39 BOOL fFatal = FALSE;
40 long lRc = 0;
41 char *pszInput = NULL;
42 char *pszOutput = NULL;
43 OPTIONS options = {TRUE, ORD_START_INTERNAL_FUNCTIONS, FALSE, TRUE};
44
45 /**************************************************************************
46 * parse arguments.
47 * options: -h or -? help
48 * -S<[+]|-> Similar to exported. (stdcall)
49 * -O<[+]|-> Remove OS2 prefix on APIs.
50 * -I:<num> Start ordinal number of internal functions.
51 * -F<[+]|-> Export intname for internal stdcall functions.
52 **************************************************************************/
53 if (argc == 1)
54 syntax();
55 argi = 1;
56 while (argi < argc && !fFatal)
57 {
58 if(argv[argi][0] == '-' || argv[argi][0] == '/')
59 {
60 switch (argv[argi][1])
61 {
62 case 's':
63 case 'S':
64 options.fSimilarToExported = argv[argi][2] != '-';
65 break;
66
67 case 'o':
68 case 'O':
69 options.fRemoveOS2APIPrefix = argv[argi][2] != '-';
70 break;
71
72 case 'i':
73 case 'I':
74 if (strlen(argv[argi]) >= 3)
75 {
76 options.ulOrdStartInternalFunctions = atol(&argv[argi][3]);
77 if (options.ulOrdStartInternalFunctions == 0)
78 kFile::StdErr.printf("warning: internal functions starts at ordinal 0!\n");
79 }
80 else
81 {
82 kFile::StdErr.printf("incorrect parameter -I:<ord>. (argi=%d, argv[argi]=%s)\n", argi, argv[argi]);
83 fFatal = TRUE;
84 }
85 break;
86
87 case 'f':
88 case 'F':
89 options.fInternalFnExportStdCallsIntName = argv[argi][2] != '-';
90 break;
91
92 case '?':
93 case 'h':
94 case 'H':
95 syntax();
96 return 0;
97
98 default:
99 kFile::StdErr.printf("incorrect parameter. (argi=%d, argv[argi]=%s)\n", argi, argv[argi]);
100 fFatal = TRUE;
101 break;
102 }
103 }
104 else
105 {
106 if (pszInput == NULL)
107 pszInput = argv[argi];
108 else if (pszOutput == NULL)
109 pszOutput = argv[argi];
110 else
111 {
112 kFile::StdErr.printf("To many files are specified!\n");
113 fFatal = TRUE;
114 }
115 }
116 argi++;
117 }
118
119 if (pszInput == NULL)
120 {
121 fFatal = TRUE;
122 kFile::StdErr.printf("Missing input file.\n");
123 }
124 else if (pszOutput == NULL)
125 {
126 fFatal = TRUE;
127 kFile::StdErr.printf("Missing output file.\n");
128 }
129
130 if (!fFatal)
131 lRc = processFile(pszInput, pszOutput, &options);
132 else
133 lRc = -1;
134
135 return (int)lRc;
136}
137
138
139/**
140 * Print syntax/help message.
141 */
142static void syntax(void)
143{
144 kFile::StdOut.printf(
145 "\n"
146 "ImpDef - Creates internal import definition file\n"
147 "------------------------------------------------\n"
148 "syntax: ImpDef.exe [-h|-?] [-S] <infile> <outfile>\n"
149 " -h or -? Syntax help. (this)\n"
150 " -F<[+]|-> Fix! Export int.name for int.functions. default: F+\n"
151 " -I:<ord> Start of internal function. default: I:%d\n"
152 " -O<[+]|-> Remove OS2 prefix on APIs. default: O-\n"
153 " -S<[+]|-> Similar to exported name. default: S+\n"
154 " infile Name of input file\n"
155 " outfile Name of output file\n"
156 "\n"
157 "Notes:\n"
158 " -S+ only works on stdcall functions (having '@' in the internal name).\n"
159 " -S+ takes the '_' and the '@..' parts from the internal name and adds it\n"
160 " to the exported name. This way the OS2 prefix is removed.\n"
161 " -O+ has no effect on stdcall functions when -S+ is set. -S+ has higher\n"
162 " precedence than -O+.\n"
163 " -O+ only removes the OS2 prefix from internal names.\n",
164 ORD_START_INTERNAL_FUNCTIONS
165 );
166}
167
168
169/**
170 *
171 * @returns 0 on success, error code on error.
172 * @param pszInput Input filename.
173 * @param pszOuput Output filename.
174 * @param pOptions Pointer to options struct.
175 * @sketch Open input file
176 * try create a kFileDef object from inputfile.
177 * Open output file.
178 * Generate output file.
179 * @remark
180 */
181static long processFile(const char *pszInput, const char *pszOutput, const POPTIONS pOptions)
182{
183 long lRc = 0;
184
185 try
186 {
187 kFile Input(pszInput);
188 try
189 {
190 kFileDef DefFile(&Input);
191 try
192 {
193 EXPORTENTRY export;
194 kFile Output(pszOutput, FALSE);
195
196 /* generate LIBRARY line */
197 Output.printf(
198 ";Internal export definition file - autogenerated by ImpDef.\n"
199 "%s\n",
200 DefFile.queryType());
201
202 /* Description line */
203 if (DefFile.queryDescription())
204 Output.printf("DESCRIPTION %s\n", DefFile.queryDescription());
205
206 /* Exports */
207 if (DefFile.findFirstExport(&export))
208 {
209 Output.printf("EXPORTS\n");
210 do
211 {
212 char szName[MAXEXPORTNAME];
213 const char *pszName;
214
215 /* validate export struct */
216 if (export.achName[0] == '\0')
217 {
218 kFile::StdErr.printf(
219 "Warning export name is missing.\n"
220 "info:\texport.achIntName=%s\n\texport.achName=%s\n\texport.ulOrdinal=%ld\n",
221 export.achIntName, export.achName, export.ulOrdinal);
222 continue;
223 }
224 if (export.ulOrdinal == ~0UL)
225 {
226 kFile::StdErr.printf(
227 "warning: export is missing ordinal value. Export is ignored\n"
228 "info:\texport.achIntName=%s\n\texport.achName=%s\n\texport.ulOrdinal=%ld\n",
229 export.achIntName, export.achName, export.ulOrdinal);
230 continue;
231 }
232
233 /* real work */
234 pszName = generateExportName(&export, &szName[0], pOptions);
235
236 Output.printf(" %-*s @%ld\n", 40, pszName, export.ulOrdinal);
237 } while (DefFile.findNextExport(&export));
238 }
239 }
240 catch (int errorcode)
241 {
242 kFile::StdErr.printf("error creating output file, '%s', errorcode 0x%x\n", pszOutput, errorcode);
243 lRc = -4;
244 }
245 }
246 catch (int errorcode)
247 {
248 kFile::StdErr.printf("%s is not a valid def file, errorcode 0x%x\n", pszInput, errorcode);
249 lRc = -3;
250 }
251 }
252 catch (int errorcode)
253 {
254 kFile::StdErr.printf( "error openining inputfile, '%s', errorcode 0x%x\n", pszInput, errorcode);
255 lRc = -2;
256 }
257
258 return lRc;
259}
260
261
262/**
263 * Generate export names according to options defines.
264 * fSimilarToExported only applies to stdcall API functions.
265 * fRemoveOS2APIPrefix only applies to APIs.
266 * fRemoveOS2APIPrefix have no effect on stdcall functions when fSimilarToExported is set.
267 * fRemoveOS2APIPrefix only applies to the internal names.
268 * @returns Pointer to buffer.
269 * @param pExport Export entry.
270 * @param pszBuffer Pointer to a string buffer which the result is returned in.
271 * @param pOptions Pointer to options-struct.
272 * @precond The export data (pExport) is valiaded.
273 * @sketch write only code... but it works (I hope).
274 * @remark
275 */
276static char *generateExportName(const PEXPORTENTRY pExport, char *pszBuffer, const POPTIONS pOptions)
277{
278 if (pExport->ulOrdinal < pOptions->ulOrdStartInternalFunctions)
279 {
280 /* API */
281 if (pOptions->fSimilarToExported)
282 {
283 if (pExport->achIntName[0] != '\0')
284 {
285 char *pszAt = strchr(&pExport->achIntName[0], '@');
286 if (pszAt != NULL && pExport->achIntName[0] == '_' && pExport->achName[0] != '"')
287 { /* stdcall - merge */
288 strcpy(pszBuffer, "_");
289 /* test for "reserved" definition file names (like HeapSize) in original def-file. */
290 if (pExport->achName[0] != '"')
291 strcat(pszBuffer, &pExport->achName[0]);
292 else
293 {
294 strcat(pszBuffer, &pExport->achName[1]);
295 pszBuffer[strlen(pszBuffer)-1] = '\0'; //remove tail '"'
296 }
297
298 strcat(pszBuffer, pszAt);
299 }
300 else
301 { /* not a stdcall - no merge but check for OS2prefix */
302 if (pOptions->fRemoveOS2APIPrefix)
303 {
304 int i = 0;
305 char *psz = pszBuffer;
306 if (pExport->achIntName[i] == '_')
307 *psz++ = pExport->achIntName[i++];
308 if (strncmp(&pExport->achIntName[i], "OS2", 3) == 0)
309 i += 3;
310 strcpy(psz, &pExport->achIntName[i]);
311 }
312 else
313 strcpy(pszBuffer, &pExport->achIntName[0]);
314 }
315 }
316 else
317 strcpy(pszBuffer, &pExport->achName[0]);
318 }
319 else if (pOptions->fRemoveOS2APIPrefix)
320 { /* removes OS2 prefix */
321 if (pExport->achIntName[0] != '\0')
322 {
323 int i = 0;
324 char *psz = pszBuffer;
325 if (pExport->achIntName[i] == '_')
326 *psz++ = pExport->achIntName[i++];
327 if (strncmp(&pExport->achIntName[i], "OS2", 3) == 0)
328 i += 3;
329 strcpy(psz, &pExport->achIntName[i]);
330 }
331 else
332 strcpy(pszBuffer, &pExport->achName[0]);
333 }
334 else
335 if (pExport->achIntName[0] != '\0')
336 strcpy(pszBuffer, &pExport->achIntName[0]);
337 else
338 strcpy(pszBuffer, &pExport->achName[0]);
339 }
340 else
341 { /* non-API functions */
342 if ((pExport->achName[0] == '\0' || (pOptions->fInternalFnExportStdCallsIntName && strchr(&pExport->achIntName[0], '@')))
343 && pExport->achIntName[0] != '\0'
344 )
345 strcpy(pszBuffer, &pExport->achIntName[0]);
346 else
347 strcpy(pszBuffer, &pExport->achName[0]);
348 }
349
350 return pszBuffer;
351}
352
Note: See TracBrowser for help on using the repository browser.