source: trunk/tools/common/kFileDef.cpp@ 824

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

Initial checkin.

File size: 15.2 KB
Line 
1/*
2 * kFileDef - Definition files.
3 *
4 * Copyright (c) 1999 knut st. osmundsen
5 *
6 */
7
8/*******************************************************************************
9* Defined Constants *
10*******************************************************************************/
11#define StringCase(psz, pszMatch) (strnicmp(psz, pszMatch, sizeof(pszMatch)-1) == 0)
12
13/*******************************************************************************
14* Header Files *
15*******************************************************************************/
16#include <os2.h>
17#include <stdio.h>
18#include <string.h>
19#include <stdlib.h>
20
21#include "kFileFormatBase.h"
22#include "kFileDef.h"
23
24
25/*******************************************************************************
26* Internal Functions *
27*******************************************************************************/
28static char *dupeString(const char *psz);
29static char *trim(char *psz);
30
31
32/**
33 * Duplicates a string.
34 * @returns Pointer to stringcopy. Remeber to delete this!
35 * @param psz Pointer to string to duplicate.
36 */
37static char *dupeString(const char *psz)
38{
39 char *pszDupe;
40 if (psz == NULL)
41 return NULL;
42 pszDupe = new char[strlen(psz)+1];
43 return strcpy(pszDupe, psz);
44}
45
46
47/**
48 * Trims a string, that is removing blank spaces at start and end.
49 * @returns Pointer to first non-blank char.
50 * @param psz Pointer to string.
51 * @result Blank at end of string is removed. ('\0' is moved to the left.)
52 */
53static char *trim(char *psz)
54{
55 int i;
56 if (psz == NULL)
57 return NULL;
58 while (*psz == ' ')
59 psz++;
60 i = strlen(psz) - 1;
61 while (i >= 0 && psz[i] == ' ')
62 i--;
63 psz[i+1] = '\0';
64 return psz;
65}
66
67
68kFileDef::kFileDef(FILE *phFile) throw(int)
69 :pszType(NULL), pszBase(NULL), pszCode(NULL), pszData(NULL), pszDescription(NULL),
70 pszExeType(NULL), pszHeapSize(NULL), pszOld(NULL), pszProtmode(NULL), pszStackSize(NULL),
71 pszStub(NULL), pSegments(NULL), pImports(NULL), pExports(NULL)
72{
73 /* determin file size */
74 if (!fseek(phFile, 0, SEEK_SET))
75 {
76 this->read(phFile);
77 }
78 else
79 throw (0x001);
80}
81
82
83/**
84 * Destructor. Frees used memory.
85 */
86kFileDef::~kFileDef()
87{
88 if (pszType != NULL) delete pszType;
89 if (pszBase != NULL) delete pszBase;
90 if (pszCode != NULL) delete pszCode;
91 if (pszData != NULL) delete pszData;
92 if (pszDescription != NULL) delete pszDescription;
93 if (pszExeType != NULL) delete pszExeType;
94 if (pszHeapSize != NULL) delete pszHeapSize;
95 if (pszOld != NULL) delete pszOld;
96 if (pszProtmode != NULL) delete pszProtmode;
97 if (pszStackSize != NULL) delete pszStackSize;
98 if (pszStub != NULL) delete pszStub;
99 while (pSegments != NULL)
100 {
101 PDEFSEGMENT p = pSegments;
102 pSegments = pSegments->pNext;
103 if (p->psz != NULL) delete p->psz;
104 delete p;
105 }
106 while (pImports != NULL)
107 {
108 PDEFIMPORT p = pImports;
109 pImports = pImports->pNext;
110 if (p->pszName != NULL) delete p->pszName;
111 if (p->pszDll != NULL) delete p->pszDll;
112 if (p->pszIntName != NULL) delete p->pszIntName;
113 delete p;
114 }
115 while (pExports != NULL)
116 {
117 PDEFEXPORT p = pExports;
118 pExports = p->pNext;
119 if (p->pszName != NULL) delete p->pszName;
120 if (p->pszIntName != NULL) delete p->pszIntName;
121 delete p;
122 }
123}
124
125
126/**
127 * Read/parse the Definition file.
128 * @param phFile Handle to file.
129 * @remark throws errorcode on error (TODO: errorhandling)
130 */
131void kFileDef::read(FILE *phFile) throw (int)
132{
133 char *pszTmp;
134 char *psz;
135 char szBuffer[256];
136
137 /* readloop */
138 psz = readln(phFile, &szBuffer[0], sizeof(szBuffer));
139 while (psz != NULL)
140 {
141 BOOL fNext = TRUE;
142
143 /* if-switch */
144 if (StringCase(psz, "LIBRARY"))
145 {
146 if (pszType != NULL) throw (0x101);
147 pszType = dupeString(psz);
148 }
149 else if (StringCase(psz, "NAME"))
150 {
151 if (pszType != NULL) throw (0x101);
152 pszType = dupeString(psz);
153 }
154 else if (StringCase(psz, "PHYSICAL DEVICE")) //gap is fixed to one space, this may be fixed in readln.
155 {
156 if (pszType != NULL) throw (0x101);
157 pszType = dupeString(psz);
158 }
159 else if (StringCase(psz, "VIRTUAL DEVICE")) //gap is fixed to one space, this may be fixed in readln.
160 {
161 if (pszType != NULL) throw (0x101);
162 pszType = dupeString(psz);
163 }
164 else if (StringCase(psz, "BASE"))
165 pszBase = dupeString(psz);
166 else if (StringCase(psz, "CODE"))
167 pszCode = dupeString(psz);
168 else if (StringCase(psz, "DATA"))
169 pszData = dupeString(psz);
170 else if (StringCase(psz, "DESCRIPTION"))
171 pszDescription = dupeString(psz);
172 else if (StringCase(psz, "EXETYPE"))
173 pszExeType = dupeString(psz);
174 else if (StringCase(psz, "HEAPSIZE"))
175 pszHeapSize = dupeString(psz);
176 else if (StringCase(psz, "OLD"))
177 pszOld = dupeString(psz);
178 else if (StringCase(psz, "PROTMODE"))
179 pszProtmode = dupeString(psz);
180 else if (StringCase(psz, "STACKSIZE"))
181 pszStackSize = dupeString(psz);
182 else if (StringCase(psz, "STUB"))
183 pszStub = dupeString(psz);
184 else if (StringCase(psz, "SEGMENTS"))
185 {
186 PDEFSEGMENT *pps = &pSegments;
187 while (!isKeyword(psz = readln(phFile, &szBuffer[0], sizeof(szBuffer))) && psz != NULL)
188 {
189 *pps = new DEFSEGMENT; memset(*pps, 0, sizeof(**pps));
190 (**pps).psz = dupeString(psz);
191 pps = &(**pps).pNext;
192 }
193 fNext = FALSE;
194 }
195 else if (StringCase(psz, "IMPORTS"))
196 {
197 PDEFIMPORT *ppi = &pImports;
198 while (!isKeyword(psz = readln(phFile, &szBuffer[0], sizeof(szBuffer))) && psz != NULL)
199 {
200 //DOSCALL1.154 or DosQueryHeaderInfo = DOSCALL1.154
201 *ppi = new DEFIMPORT; memset(*ppi, 0, sizeof(**ppi));
202 (**ppi).ulOrdinal = 0xffffffffUL;
203
204 if ((pszTmp = strchr(psz, '=')) != NULL)
205 {
206 *pszTmp = '\0';
207 (**ppi).pszIntName = dupeString(trim(psz));
208 psz = pszTmp + 1;
209 }
210 if ((pszTmp = strchr(psz, '.')) != NULL)
211 {
212 *pszTmp = '\0';
213 (**ppi).pszDll = dupeString(trim(psz));
214 psz = pszTmp + 1;
215 }
216 psz = trim(psz);
217 if (*psz >= '0' && *psz <= '9')
218 {
219 (**ppi).ulOrdinal = strtol(psz, &pszTmp, 0);
220 if (psz ==pszTmp) throw(0x102);
221 }
222 else
223 (**ppi).pszName = dupeString(psz);
224 ppi = &(**ppi).pNext;
225 }
226 fNext = FALSE;
227 }
228 else if (StringCase(psz, "EXPORTS"))
229 {
230 PDEFEXPORT *ppe = &pExports;
231 while (!isKeyword(psz = readln(phFile, &szBuffer[0], sizeof(szBuffer))) && psz != NULL)
232 {
233 /* CloseHandle = CloseHandle@4 @1234 RESIDENTNAME 2 */
234 *ppe = new DEFEXPORT; memset(*ppe, 0, sizeof(**ppe));
235 (**ppe).ulOrdinal = 0xffffffffUL;
236 (**ppe).cParam = 0xffffffffUL;
237
238 /* look for '=' */
239 pszTmp = strchr(psz, '=');
240 if (pszTmp != NULL)
241 { /* CloseHandle = CloseHandle@4 */
242 *pszTmp ='\0';
243 (**ppe).pszName = dupeString(trim(psz));
244 psz = trim(pszTmp + 1);
245
246 pszTmp = strchr(psz, ' ');
247 if (pszTmp != NULL)
248 *pszTmp = '\0';
249 (**ppe).pszIntName = dupeString(trim(psz));
250 if (pszTmp != NULL)
251 psz = pszTmp + 1;
252 else
253 psz = NULL;
254 }
255 else
256 { /* CloseHandle (no '= CloseHandle@4')*/
257 pszTmp = strchr(psz, ' ');
258 if (pszTmp != NULL)
259 *pszTmp = '\0';
260 (**ppe).pszName = dupeString(trim(psz));
261 if (pszTmp != NULL)
262 psz = pszTmp + 1;
263 else
264 psz = NULL;
265 }
266
267 if (psz != NULL)
268 { /* @1234 RESIDENTNAME 2 */
269 pszTmp = strchr(psz, '@');
270 if (pszTmp)
271 { /* @1234 RESIDENTNAME 2 */
272 psz = pszTmp + 1;
273 (**ppe).ulOrdinal = strtol(psz, &pszTmp, 0);
274 if (pszTmp == psz) throw (0x103);
275 psz = trim(pszTmp);
276
277 if (*psz != '\0')
278 { /* RESIDENTNAME 2 */
279 if (StringCase(psz, "RESIDENTNAME"))
280 {
281 (**ppe).fResident = TRUE;
282 psz = trim(psz + sizeof("RESIDENTNAME") - 1);
283 }
284 else if (StringCase(psz, "NONAME"))
285 {
286 (**ppe).fResident = FALSE;
287 psz = trim(psz + sizeof("NONAME") - 1);
288 }
289 }
290 else
291 {
292 (**ppe).fResident = (**ppe).ulOrdinal == 0xffffffffUL;
293 }
294 }
295
296 if (*psz != '\0')
297 { /* 2 */
298 (**ppe).cParam = strtol(psz, &pszTmp, 0);
299 if (pszTmp == psz) throw (0x104);
300 }
301 }
302
303 ppe = &(**ppe).pNext;
304 }
305 fNext = FALSE;
306 }
307 else
308 throw(0x105);
309
310 /* next ? */
311 if (fNext)
312 psz = readln(phFile, &szBuffer[0], sizeof(szBuffer));
313 }
314
315 /* sanity check */
316 if (pszType == NULL)
317 throw (0x106);
318}
319
320
321/**
322 * Reads first meaning full line from a file into a buffer.
323 * @returns Pointer to buffer on success; NULL on error.
324 * @param phFile Filea handle.
325 * @param pszBuffer Pointer to buffer.
326 * @param cbBuffer Size of buffer.
327 * @remark tabs are expanded. string is trimmed. comments removed.
328 */
329char *kFileDef::readln(FILE *phFile, char *pszBuffer, int cbBuffer) throw (int)
330{
331 int i;
332 int cch;
333
334 do
335 {
336 /* read line */
337 if (!fgets(pszBuffer, cbBuffer, phFile))
338 {
339 if (feof(phFile))
340 return FALSE;
341 else
342 throw (0x201);
343 }
344
345 /* check for and remove comments, and get string length. */
346 cch = 0;
347 while (pszBuffer[cch] != '\0' && pszBuffer[cch] != ';')
348 cch++;
349 pszBuffer[cch] = '\0';
350
351 if (cch > 0)
352 {
353 /* remove '\t' - tab is trouble some! */
354 for (i = 0; i < cch; i++)
355 if (pszBuffer[i] == '\t')
356 pszBuffer[i] = ' ';
357
358 /* trim line - right */
359 i = cch - 1;
360 while (i >= 0 &&
361 (
362 pszBuffer[i] == '\n' ||
363 pszBuffer[i] == '\r' ||
364 pszBuffer[i] == ' '
365 ))
366 i--;
367 pszBuffer[++i] = '\0';
368 cch = i;
369
370 /* trim line - left */
371 i = 0;
372 while (i < cch && pszBuffer[i] == ' ')
373 i++;
374 cch -= i;
375 if (i > 0)
376 memmove(pszBuffer, &pszBuffer[i], cch + 1);
377 }
378 } while ((*pszBuffer == ';' || cch == 0) && !feof(phFile));
379
380 return !(*pszBuffer == ';' || cch == 0) ? pszBuffer : NULL;
381}
382
383
384/**
385 * Checks for keyword.
386 * @returns TRUE - keyword; FALSE - not keyword;
387 * @param psz Pointer to word/string to check.
388 * @remark TODO - we are going to check WORDS.
389 */
390BOOL kFileDef::isKeyword(const char *psz)
391{
392 return psz != NULL
393 &&
394 (
395 StringCase(psz, "LIBRARY") ||
396 StringCase(psz, "NAME") ||
397 StringCase(psz, "PHYSICAL DEVICE") || //gap is fixed to one space, this may be fixed in readln.
398 StringCase(psz, "VIRTUAL DEVICE") || //gap is fixed to one space, this may be fixed in readln.
399 StringCase(psz, "BASE") ||
400 StringCase(psz, "CODE") ||
401 StringCase(psz, "DATA") ||
402 StringCase(psz, "DESCRIPTION") ||
403 StringCase(psz, "EXETYPE") ||
404 StringCase(psz, "HEAPSIZE") ||
405 StringCase(psz, "OLD") ||
406 StringCase(psz, "STACKSIZE") ||
407 StringCase(psz, "STUB") ||
408 StringCase(psz, "SEGMENTS") ||
409 StringCase(psz, "IMPORTS") ||
410 StringCase(psz, "EXPORTS")
411 );
412}
413
414
415/**
416 * Queries the module name.
417 * @returns Success indicator.
418 * @param pszBuffer Pointer to string buffer which is to hold the module name upon return.
419 * @remark Assumes that pszBuffer is large enough.
420 */
421BOOL kFileDef::queryModuleName(char *pszBuffer)
422{
423 char *psz;
424
425 if (pszType != NULL && StringCase(pszType, "LIBRARY"))
426 {
427 psz = pszType + sizeof("LIBRARY") - 1;
428 while (*psz == ' ')
429 psz++;
430 while (*psz != '\0' && *psz != ' ')
431 *pszBuffer++ = *psz++;
432 *pszBuffer = '\0';
433 }
434 else
435 return FALSE;
436 return TRUE;
437}
438
439
440/**
441 * Finds the first exports.
442 * @returns Success indicator. TRUE / FALSE.
443 * @param pExport Pointer to export structure.
444 * @remark
445 */
446BOOL kFileDef::findFirstExport(PEXPORTENTRY pExport)
447{
448 if (pExports != NULL && pExport != NULL)
449 {
450 pExport->ulOrdinal = pExports->ulOrdinal;
451 if (pExports->pszName != NULL)
452 strcpy(&pExport->achName[0], pExports->pszName);
453 else
454 pExport->achName[0] = '\0';
455 if (pExports->pszIntName)
456 strcpy(&pExport->achIntName[0], pExports->pszIntName);
457 else
458 pExport->achIntName[0] = '\0';
459 pExport->pv = (void*)pExports->pNext;
460 }
461 else
462 return FALSE;
463 return TRUE;
464}
465
466
467/**
468 * Finds the next export.
469 * @returns Success indicator. TRUE / FALSE.
470 * @param pExport Pointer to export structure.
471 * @remark
472 */
473BOOL kFileDef::findNextExport(PEXPORTENTRY pExport)
474{
475 if (pExport != NULL && pExport->pv != NULL)
476 {
477 PDEFEXPORT pExp = (PDEFEXPORT)pExport->pv;
478
479 pExport->ulOrdinal = pExp->ulOrdinal;
480 if (pExp->pszName != NULL)
481 strcpy(&pExport->achName[0], pExp->pszName);
482 else
483 pExport->achName[0] = '\0';
484 if (pExp->pszIntName)
485 strcpy(&pExport->achIntName[0], pExp->pszIntName);
486 else
487 pExport->achIntName[0] = '\0';
488 pExport->pv = (void*)pExp->pNext;
489 }
490 else
491 return FALSE;
492 return TRUE;
493}
494
495
Note: See TracBrowser for help on using the repository browser.