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
RevLine 
[8002]1/* $Id: ImpDef.cpp,v 1.8 2002-02-24 02:44:40 bird Exp $ */
[825]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*******************************************************************************/
[8002]12//#include <os2.h>
[825]13#include <stdio.h>
14#include <string.h>
[867]15#include <stdlib.h>
[8002]16
[21916]17#include <string>
18#include <set>
19
[8002]20#include "kTypes.h"
21#include "kError.h"
[4402]22#include "kFile.h"
[8002]23#include "kFileInterfaces.h"
[825]24#include "kFileFormatBase.h"
25#include "kFileDef.h"
26
[8002]27#include "ImpDef.h"
[825]28
[8002]29
[825]30/*******************************************************************************
31* Internal Functions *
32*******************************************************************************/
33static void syntax(void);
34static long processFile(const char *pszInput, const char *pszOutput, const POPTIONS pOptions);
[5531]35static char *generateExportName(const kExportEntry * pExport, char *pszBuffer, const POPTIONS pOptions);
[825]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;
[8002]47 KBOOL fFatal = FALSE;
[825]48 long lRc = 0;
49 char *pszInput = NULL;
50 char *pszOutput = NULL;
[867]51 OPTIONS options = {TRUE, ORD_START_INTERNAL_FUNCTIONS, FALSE, TRUE};
[825]52
53 /**************************************************************************
54 * parse arguments.
55 * options: -h or -? help
56 * -S<[+]|-> Similar to exported. (stdcall)
57 * -O<[+]|-> Remove OS2 prefix on APIs.
[867]58 * -I:<num> Start ordinal number of internal functions.
59 * -F<[+]|-> Export intname for internal stdcall functions.
[825]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
[867]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)
[4402]86 kFile::StdErr.printf("warning: internal functions starts at ordinal 0!\n");
[867]87 }
88 else
89 {
[4402]90 kFile::StdErr.printf("incorrect parameter -I:<ord>. (argi=%d, argv[argi]=%s)\n", argi, argv[argi]);
[867]91 fFatal = TRUE;
92 }
93 break;
94
95 case 'f':
96 case 'F':
97 options.fInternalFnExportStdCallsIntName = argv[argi][2] != '-';
98 break;
99
[825]100 case '?':
101 case 'h':
102 case 'H':
103 syntax();
104 return 0;
105
106 default:
[4402]107 kFile::StdErr.printf("incorrect parameter. (argi=%d, argv[argi]=%s)\n", argi, argv[argi]);
[825]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 {
[4402]120 kFile::StdErr.printf("To many files are specified!\n");
[825]121 fFatal = TRUE;
122 }
123 }
124 argi++;
125 }
126
127 if (pszInput == NULL)
128 {
129 fFatal = TRUE;
[4402]130 kFile::StdErr.printf("Missing input file.\n");
[825]131 }
132 else if (pszOutput == NULL)
133 {
134 fFatal = TRUE;
[4402]135 kFile::StdErr.printf("Missing output file.\n");
[825]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{
[4402]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 );
[825]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{
[21916]191 std::set<std::string> exports;
192
[825]193 long lRc = 0;
194
[4402]195 try
[825]196 {
[8002]197 kFile * pInput = new kFile(pszInput);
[825]198 try
199 {
[8002]200 kFileDef * pDefFile = new kFileDef(pInput);
[4402]201 try
[825]202 {
[8002]203 kFile * pOutput = new kFile(pszOutput, FALSE);
[21916]204 kExportEntry exp;
[825]205
206 /* generate LIBRARY line */
[8002]207 pOutput->printf(
[4402]208 ";Internal export definition file - autogenerated by ImpDef.\n"
209 "%s\n",
[8002]210 pDefFile->queryType());
[4402]211
212 /* Description line */
[8002]213 if (pDefFile->queryDescription())
214 pOutput->printf("DESCRIPTION '%s'\n", pDefFile->queryDescription());
[4402]215
216 /* Exports */
[21916]217 if (pDefFile->exportFindFirst(&exp))
[825]218 {
[8002]219 pOutput->printf("EXPORTS\n");
[825]220 do
221 {
[21916]222 char szName[MAXEXPORTNAME + 2 /*quotes*/];
[825]223 const char *pszName;
224
225 /* validate export struct */
[21916]226 if (exp.achName[0] == '\0')
[825]227 {
[4402]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",
[21916]231 exp.achIntName, exp.achName, exp.ulOrdinal);
[825]232 continue;
233 }
[21916]234 if (exp.ulOrdinal == ~0UL)
[825]235 {
[4402]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",
[21916]239 exp.achIntName, exp.achName, exp.ulOrdinal);
[825]240 continue;
241 }
242
243 /* real work */
[21916]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;
[825]250
[21916]251 pOutput->printf(" %-*s @%ld\n", 40, pszName, exp.ulOrdinal);
252 }
253 } while (pDefFile->exportFindNext(&exp));
[8002]254 pOutput->setSize();
255 delete pOutput;
[825]256 }
257 }
[8002]258 catch (kError err)
[825]259 {
[8002]260 kFile::StdErr.printf("error creating output file, '%s', errorcode 0x%x\n", pszOutput, err.getErrno());
[825]261 lRc = -4;
262 }
[8002]263 delete pDefFile;
[825]264 }
[8002]265 catch (kError err)
[825]266 {
[8002]267 kFile::StdErr.printf("%s is not a valid def file, errorcode 0x%x\n", pszInput, err.getErrno());
[825]268 lRc = -3;
269 }
[8002]270 //delete pInput; - not needed done by ~kFileFormatBase!
[825]271 }
[8002]272 catch (kError err)
[825]273 {
[8002]274 kFile::StdErr.printf( "error openining inputfile, '%s', errorcode 0x%x\n", pszInput, err.getErrno());
[825]275 lRc = -2;
276 }
277
278 return lRc;
279}
280
281
282/**
283 * Generate export names according to options defines.
[867]284 * fSimilarToExported only applies to stdcall API functions.
[825]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 */
[5531]296static char *generateExportName(const kExportEntry * pExport, char *pszBuffer, const POPTIONS pOptions)
[825]297{
[867]298 if (pExport->ulOrdinal < pOptions->ulOrdStartInternalFunctions)
[825]299 {
[867]300 /* API */
301 if (pOptions->fSimilarToExported)
[825]302 {
[867]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 }
[825]320 else
[867]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]);
[825]334 }
335 }
336 else
[867]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]);
[825]350 }
[867]351 else
352 strcpy(pszBuffer, &pExport->achName[0]);
[825]353 }
354 else
[867]355 if (pExport->achIntName[0] != '\0')
356 strcpy(pszBuffer, &pExport->achIntName[0]);
357 else
358 strcpy(pszBuffer, &pExport->achName[0]);
[825]359 }
360 else
[867]361 { /* non-API functions */
362 if ((pExport->achName[0] == '\0' || (pOptions->fInternalFnExportStdCallsIntName && strchr(&pExport->achIntName[0], '@')))
363 && pExport->achIntName[0] != '\0'
364 )
[825]365 strcpy(pszBuffer, &pExport->achIntName[0]);
366 else
367 strcpy(pszBuffer, &pExport->achName[0]);
[867]368 }
[825]369
370 return pszBuffer;
371}
372
Note: See TracBrowser for help on using the repository browser.