source: trunk/tools/impdef/ImpDef.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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