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

Last change on this file since 6496 was 5531, checked in by bird, 24 years ago

Second iteration of the kFile* classes and interfaces.

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