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

Last change on this file since 10367 was 8002, checked in by bird, 24 years ago

New kFile* classes.

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