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

Last change on this file since 867 was 867, checked in by bird, 26 years ago

New options. Will now handle 'internal' functions correctly.

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