source: trunk/tools/common/kFileDef.cpp

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

Merge branch gcc-kmk to trunk.

File size: 29.6 KB
RevLine 
[9164]1/* $Id: kFileDef.cpp,v 1.13 2002-08-29 07:59:24 bird Exp $
[8003]2 *
[824]3 * kFileDef - Definition files.
4 *
[8003]5 * Copyright (c) 1999-2001 knut st. osmundsen
[824]6 *
7 */
8
9/*******************************************************************************
10* Defined Constants *
11*******************************************************************************/
[4804]12#define StringCase(psz, pszMatch) (strnicmp(psz, pszMatch, sizeof(pszMatch)-1) == 0 \
13 && ( psz[sizeof(pszMatch)-1] == '\0' \
14 || psz[sizeof(pszMatch)-1] == ' ' \
15 || psz[sizeof(pszMatch)-1] == '\n' \
16 || psz[sizeof(pszMatch)-1] == '\r' \
17 || psz[sizeof(pszMatch)-1] == '\t' \
18 ) \
19 )
[824]20
21/*******************************************************************************
22* Header Files *
23*******************************************************************************/
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27
[8003]28#include "kTypes.h"
29#include "kError.h"
[4402]30#include "kFile.h"
[824]31#include "kFileFormatBase.h"
[8003]32#include "kFileInterfaces.h"
[824]33#include "kFileDef.h"
34
[8003]35
[5531]36/*******************************************************************************
37* Global Variables *
38*******************************************************************************/
39#if 0
40static kFileDef tst((kFile*)NULL);
41#endif
[824]42
[5531]43
[824]44/*******************************************************************************
45* Internal Functions *
46*******************************************************************************/
[8003]47static char *dupeString(const char *psz, KBOOL fSkipFirstWord = FALSE);
[824]48static char *trim(char *psz);
[4402]49static char *ltrim(const char *psz);
[2759]50static char *removeFnutts(char *pszStr);
[4402]51inline char upcase(char ch);
52static char *stristr(const char *pszStr, const char *pszSubStr);
[824]53
[4402]54
[824]55/**
56 * Duplicates a string.
[4402]57 * @returns Pointer to stringcopy. Remeber to delete this!
58 * @param psz Pointer to string to duplicate.
59 * @param fSkipFirstWord Skips the first word before duplicating the string.
[824]60 */
[8003]61static char *dupeString(const char *psz, KBOOL fSkipFirstWord/* = FALSE*/)
[824]62{
63 char *pszDupe;
64 if (psz == NULL)
65 return NULL;
[4402]66
67 if (fSkipFirstWord)
68 {
69 while (*psz != ' ' && *psz != '\t' && *psz != '\n' && *psz != '\r' && *psz != '\0')
70 psz++;
71 psz = ltrim(psz);
72 }
73
[824]74 pszDupe = new char[strlen(psz)+1];
[4402]75 strcpy(pszDupe, psz);
76 if (fSkipFirstWord)
77 return removeFnutts(pszDupe);
78 return pszDupe;
[824]79}
80
81
82/**
83 * Trims a string, that is removing blank spaces at start and end.
84 * @returns Pointer to first non-blank char.
85 * @param psz Pointer to string.
86 * @result Blank at end of string is removed. ('\0' is moved to the left.)
87 */
88static char *trim(char *psz)
89{
90 int i;
91 if (psz == NULL)
92 return NULL;
[4402]93 while (*psz == ' ' || *psz == '\t')
[824]94 psz++;
95 i = strlen(psz) - 1;
[4402]96 while (i >= 0 && (psz[i] == ' ' || psz[i] == '\t'))
[824]97 i--;
98 psz[i+1] = '\0';
99 return psz;
100}
101
102
[4402]103/**
104 * Trims a string, that is removing blank spaces at start and end.
105 * @returns Pointer to first non-blank char.
106 * @param psz Pointer to string.
107 * @result Blank at end of string is removed. ('\0' is moved to the left.)
108 */
109static char *ltrim(const char *psz)
110{
111 if (psz == NULL)
112 return NULL;
113
114 while (*psz == ' ' || *psz == '\t')
115 psz++;
116 return (char *)psz;
117}
118
119
120
[21916]121kFileDef::kFileDef(kFile *pFile) throw (kError) :
[8003]122 kFileFormatBase(pFile),
123 pszType(NULL), pszModName(NULL), pszBase(NULL), pszCode(NULL), pszData(NULL), pszDescription(NULL),
[824]124 pszExeType(NULL), pszHeapSize(NULL), pszOld(NULL), pszProtmode(NULL), pszStackSize(NULL),
[4402]125 pszStub(NULL), pSegments(NULL), pImports(NULL), pExports(NULL),
126 fProgram(FALSE), fLibrary(FALSE), fPhysicalDevice(FALSE), fVirtualDevice(FALSE),
127 fInitInstance(FALSE), fTermInstance(FALSE), fInitGlobal(FALSE), fTermGlobal(FALSE),
128 chAppType(kFileDef::unknown)
[824]129{
[8003]130 pFile->setThrowOnErrors();
131 pFile->start();
132 read(pFile);
[4426]133 }
[824]134
135
136/**
137 * Destructor. Frees used memory.
138 */
[21916]139kFileDef::~kFileDef() throw (kError)
[824]140{
141 if (pszType != NULL) delete pszType;
142 if (pszBase != NULL) delete pszBase;
143 if (pszCode != NULL) delete pszCode;
144 if (pszData != NULL) delete pszData;
145 if (pszDescription != NULL) delete pszDescription;
146 if (pszExeType != NULL) delete pszExeType;
147 if (pszHeapSize != NULL) delete pszHeapSize;
148 if (pszOld != NULL) delete pszOld;
149 if (pszProtmode != NULL) delete pszProtmode;
150 if (pszStackSize != NULL) delete pszStackSize;
151 if (pszStub != NULL) delete pszStub;
152 while (pSegments != NULL)
153 {
154 PDEFSEGMENT p = pSegments;
155 pSegments = pSegments->pNext;
156 if (p->psz != NULL) delete p->psz;
157 delete p;
158 }
159 while (pImports != NULL)
160 {
161 PDEFIMPORT p = pImports;
162 pImports = pImports->pNext;
163 if (p->pszName != NULL) delete p->pszName;
164 if (p->pszDll != NULL) delete p->pszDll;
165 if (p->pszIntName != NULL) delete p->pszIntName;
166 delete p;
167 }
168 while (pExports != NULL)
169 {
170 PDEFEXPORT p = pExports;
171 pExports = p->pNext;
172 if (p->pszName != NULL) delete p->pszName;
173 if (p->pszIntName != NULL) delete p->pszIntName;
174 delete p;
175 }
176}
177
178
179/**
180 * Read/parse the Definition file.
[4402]181 * @param pFile Pointer to fileobject.
182 * @remark throws errorcode on error (TODO: errorhandling)
[824]183 */
[21916]184void kFileDef::read(kFile *pFile) throw (kError)
[824]185{
186 char *pszTmp;
187 char *psz;
188 char szBuffer[256];
[9162]189 char ch;
[824]190
191 /* readloop */
[4402]192 psz = readln(pFile, &szBuffer[0], sizeof(szBuffer));
[824]193 while (psz != NULL)
194 {
[8003]195 KBOOL fNext = TRUE;
[824]196
197 /* if-switch */
198 if (StringCase(psz, "LIBRARY"))
199 {
[8003]200 if (pszType != NULL) throw (kError(kError::DEF_MULIPLE_MODULE_STATEMENT));
[824]201 pszType = dupeString(psz);
[4402]202 fLibrary = TRUE;
203 if (!setModuleName())
[8003]204 throw (kError(kError::DEF_BAD_LIBRARY_STATEMENT));
[4402]205 fInitInstance = stristr(pszType, "INITINSTANCE") != NULL;
[9133]206 fInitGlobal = stristr(pszType, "INITGLOBAL") != NULL;
[4402]207 fTermInstance = stristr(pszType, "TERMINSTANCE") != NULL;
208 fTermGlobal = stristr(pszType, "TERMGLOBAL") != NULL || !fTermInstance;
[824]209 }
210 else if (StringCase(psz, "NAME"))
211 {
[8003]212 if (pszType != NULL) throw (kError(kError::DEF_MULIPLE_MODULE_STATEMENT));
[824]213 pszType = dupeString(psz);
[4402]214 fProgram = TRUE;
215 setModuleName();
216 if (stristr(pszType, "WINDOWAPI"))
217 chAppType = kFileDef::pm;
218 else if (stristr(pszType, "NOTWINDOWCOMPAT"))
219 chAppType = kFileDef::fullscreen;
220 else if (stristr(pszType, "WINDOWCOMPAT"))
221 chAppType = kFileDef::pmvio;
222 else
223 chAppType = kFileDef::unknown;
[824]224 }
225 else if (StringCase(psz, "PHYSICAL DEVICE")) //gap is fixed to one space, this may be fixed in readln.
226 {
[8003]227 if (pszType != NULL) throw (kError(kError::DEF_MULIPLE_MODULE_STATEMENT));
[824]228 pszType = dupeString(psz);
[4402]229 fPhysicalDevice = TRUE;
230 setModuleName();
[824]231 }
232 else if (StringCase(psz, "VIRTUAL DEVICE")) //gap is fixed to one space, this may be fixed in readln.
233 {
[8003]234 if (pszType != NULL) throw (kError(kError::DEF_MULIPLE_MODULE_STATEMENT));
[824]235 pszType = dupeString(psz);
[4402]236 fVirtualDevice = TRUE;
237 setModuleName();
[824]238 }
239 else if (StringCase(psz, "BASE"))
[4402]240 pszBase = dupeString(psz, TRUE);
[824]241 else if (StringCase(psz, "CODE"))
[4402]242 pszCode = dupeString(psz, TRUE);
[824]243 else if (StringCase(psz, "DATA"))
[4402]244 pszData = dupeString(psz, TRUE);
[824]245 else if (StringCase(psz, "DESCRIPTION"))
[4402]246 pszDescription = dupeString(psz, TRUE);
[824]247 else if (StringCase(psz, "EXETYPE"))
[4402]248 pszExeType = dupeString(psz, TRUE);
[824]249 else if (StringCase(psz, "HEAPSIZE"))
[4402]250 pszHeapSize = dupeString(psz, TRUE);
[824]251 else if (StringCase(psz, "OLD"))
[4402]252 pszOld = dupeString(psz, TRUE);
[824]253 else if (StringCase(psz, "PROTMODE"))
[4402]254 pszProtmode = dupeString(psz, TRUE);
[824]255 else if (StringCase(psz, "STACKSIZE"))
[4402]256 pszStackSize = dupeString(psz, TRUE);
[824]257 else if (StringCase(psz, "STUB"))
[4402]258 pszStub = dupeString(psz, TRUE);
[824]259 else if (StringCase(psz, "SEGMENTS"))
260 {
261 PDEFSEGMENT *pps = &pSegments;
[4402]262 while (!isKeyword(psz = readln(pFile, &szBuffer[0], sizeof(szBuffer))) && psz != NULL)
[824]263 {
264 *pps = new DEFSEGMENT; memset(*pps, 0, sizeof(**pps));
265 (**pps).psz = dupeString(psz);
[9162]266
267 printf("debug: parsing: %s\n", psz);
268 /* seg name */
269 (**pps).pszName = ltrim((**pps).psz);
270 ch = *(**pps).pszName;
271 if (ch == '\'' || ch == '\"')
272 pszTmp = strchr(++(**pps).pszName, ch);
273 else
274 pszTmp = strpbrk((**pps).pszName, " \t");
275 if (pszTmp)
276 {
277 *pszTmp = '\0';
278
279 /* class ? */
280 pszTmp = ltrim(pszTmp + 1);
281 if (!strnicmp(pszTmp, "CLASS", 5))
282 {
283 (**pps).pszClass = ltrim(pszTmp + 5);
284 ch = *(**pps).pszClass;
285 if (ch == '\'' || ch == '\"')
286 pszTmp = strchr(++(**pps).pszClass, ch);
287 else
288 pszTmp = strpbrk((**pps).pszClass, " \t");
289 if (pszTmp)
290 {
291 *pszTmp++ = '\0';
292 }
293 }
294 if (pszTmp)
295 {
296 /* attribs */
297 (**pps).pszAttr = trim(pszTmp);
298 if (!*(**pps).pszAttr)
299 (**pps).pszAttr = NULL;
300 }
301 }
302
303 printf("debug: pszName=%s\n", (**pps).pszName);
304 printf("debug: pszClass=%s\n", (**pps).pszClass);
305 printf("debug: pszAttr=%s\n", (**pps).pszAttr);
306 /* next */
[824]307 pps = &(**pps).pNext;
308 }
309 fNext = FALSE;
310 }
311 else if (StringCase(psz, "IMPORTS"))
312 {
313 PDEFIMPORT *ppi = &pImports;
[4402]314 while (!isKeyword(psz = readln(pFile, &szBuffer[0], sizeof(szBuffer))) && psz != NULL)
[824]315 {
316 //DOSCALL1.154 or DosQueryHeaderInfo = DOSCALL1.154
317 *ppi = new DEFIMPORT; memset(*ppi, 0, sizeof(**ppi));
318 (**ppi).ulOrdinal = 0xffffffffUL;
319
320 if ((pszTmp = strchr(psz, '=')) != NULL)
321 {
322 *pszTmp = '\0';
323 (**ppi).pszIntName = dupeString(trim(psz));
324 psz = pszTmp + 1;
325 }
326 if ((pszTmp = strchr(psz, '.')) != NULL)
327 {
328 *pszTmp = '\0';
329 (**ppi).pszDll = dupeString(trim(psz));
330 psz = pszTmp + 1;
331 }
332 psz = trim(psz);
333 if (*psz >= '0' && *psz <= '9')
334 {
335 (**ppi).ulOrdinal = strtol(psz, &pszTmp, 0);
[8003]336 if (psz ==pszTmp) throw (kError(kError::DEF_BAD_IMPORT));
[824]337 }
338 else
339 (**ppi).pszName = dupeString(psz);
340 ppi = &(**ppi).pNext;
341 }
342 fNext = FALSE;
343 }
344 else if (StringCase(psz, "EXPORTS"))
345 {
346 PDEFEXPORT *ppe = &pExports;
[4402]347 while (!isKeyword(psz = readln(pFile, &szBuffer[0], sizeof(szBuffer))) && psz != NULL)
[824]348 {
349 /* CloseHandle = CloseHandle@4 @1234 RESIDENTNAME 2 */
350 *ppe = new DEFEXPORT; memset(*ppe, 0, sizeof(**ppe));
351 (**ppe).ulOrdinal = 0xffffffffUL;
352 (**ppe).cParam = 0xffffffffUL;
353
354 /* look for '=' */
355 pszTmp = strchr(psz, '=');
356 if (pszTmp != NULL)
357 { /* CloseHandle = CloseHandle@4 */
358 *pszTmp ='\0';
359 (**ppe).pszName = dupeString(trim(psz));
360 psz = trim(pszTmp + 1);
361
362 pszTmp = strchr(psz, ' ');
363 if (pszTmp != NULL)
364 *pszTmp = '\0';
365 (**ppe).pszIntName = dupeString(trim(psz));
366 if (pszTmp != NULL)
367 psz = pszTmp + 1;
368 else
369 psz = NULL;
370 }
371 else
372 { /* CloseHandle (no '= CloseHandle@4')*/
373 pszTmp = strchr(psz, ' ');
374 if (pszTmp != NULL)
375 *pszTmp = '\0';
376 (**ppe).pszName = dupeString(trim(psz));
377 if (pszTmp != NULL)
378 psz = pszTmp + 1;
379 else
380 psz = NULL;
381 }
382
383 if (psz != NULL)
384 { /* @1234 RESIDENTNAME 2 */
385 pszTmp = strchr(psz, '@');
386 if (pszTmp)
387 { /* @1234 RESIDENTNAME 2 */
388 psz = pszTmp + 1;
389 (**ppe).ulOrdinal = strtol(psz, &pszTmp, 0);
[8003]390 if (pszTmp == psz) throw (kError(kError::DEF_BAD_EXPORT));
[824]391 psz = trim(pszTmp);
392
393 if (*psz != '\0')
394 { /* RESIDENTNAME 2 */
395 if (StringCase(psz, "RESIDENTNAME"))
396 {
397 (**ppe).fResident = TRUE;
398 psz = trim(psz + sizeof("RESIDENTNAME") - 1);
399 }
400 else if (StringCase(psz, "NONAME"))
401 {
402 (**ppe).fResident = FALSE;
403 psz = trim(psz + sizeof("NONAME") - 1);
404 }
405 }
406 else
407 {
408 (**ppe).fResident = (**ppe).ulOrdinal == 0xffffffffUL;
409 }
410 }
411
412 if (*psz != '\0')
413 { /* 2 */
414 (**ppe).cParam = strtol(psz, &pszTmp, 0);
[8003]415 if (pszTmp == psz) throw (kError(kError::DEF_BAD_EXPORT));
[824]416 }
417 }
418
[2759]419 removeFnutts((**ppe).pszIntName);
420 removeFnutts((**ppe).pszName);
[824]421 ppe = &(**ppe).pNext;
422 }
423 fNext = FALSE;
424 }
425 else
[8003]426 throw (kError(kError::DEF_UNKOWN_VERB));
[824]427
428 /* next ? */
429 if (fNext)
[4402]430 psz = readln(pFile, &szBuffer[0], sizeof(szBuffer));
[824]431 }
432
433 /* sanity check */
434 if (pszType == NULL)
[8003]435 throw (kError(kError::DEF_NO_MODULE_STATEMENT));
[824]436}
437
438
439/**
440 * Reads first meaning full line from a file into a buffer.
441 * @returns Pointer to buffer on success; NULL on error.
[4402]442 * @param pFile Pointer to fileobject to read line from.
[824]443 * @param pszBuffer Pointer to buffer.
444 * @param cbBuffer Size of buffer.
445 * @remark tabs are expanded. string is trimmed. comments removed.
446 */
[21916]447char *kFileDef::readln(kFile *pFile, char *pszBuffer, int cbBuffer) throw (kError)
[824]448{
449 int i;
450 int cch;
451
452 do
453 {
454 /* read line */
[8003]455 if (pFile->readln(pszBuffer, cbBuffer))
[824]456 {
[4402]457 if (!pFile->isEOF())
[8003]458 throw (kError(pFile->getLastError()));
459 return NULL;
[824]460 }
461
462 /* check for and remove comments, and get string length. */
463 cch = 0;
464 while (pszBuffer[cch] != '\0' && pszBuffer[cch] != ';')
465 cch++;
466 pszBuffer[cch] = '\0';
467
468 if (cch > 0)
469 {
470 /* remove '\t' - tab is trouble some! */
471 for (i = 0; i < cch; i++)
472 if (pszBuffer[i] == '\t')
473 pszBuffer[i] = ' ';
474
475 /* trim line - right */
476 i = cch - 1;
477 while (i >= 0 &&
478 (
479 pszBuffer[i] == '\n' ||
480 pszBuffer[i] == '\r' ||
481 pszBuffer[i] == ' '
482 ))
483 i--;
484 pszBuffer[++i] = '\0';
485 cch = i;
486
487 /* trim line - left */
488 i = 0;
489 while (i < cch && pszBuffer[i] == ' ')
490 i++;
491 cch -= i;
492 if (i > 0)
493 memmove(pszBuffer, &pszBuffer[i], cch + 1);
494 }
[4402]495 } while ((*pszBuffer == ';' || cch == 0) && !pFile->isEOF());
[824]496
497 return !(*pszBuffer == ';' || cch == 0) ? pszBuffer : NULL;
498}
499
500
501/**
502 * Checks for keyword.
503 * @returns TRUE - keyword; FALSE - not keyword;
504 * @param psz Pointer to word/string to check.
505 * @remark TODO - we are going to check WORDS.
506 */
[8003]507KBOOL kFileDef::isKeyword(const char *psz)
[824]508{
509 return psz != NULL
510 &&
511 (
512 StringCase(psz, "LIBRARY") ||
513 StringCase(psz, "NAME") ||
514 StringCase(psz, "PHYSICAL DEVICE") || //gap is fixed to one space, this may be fixed in readln.
515 StringCase(psz, "VIRTUAL DEVICE") || //gap is fixed to one space, this may be fixed in readln.
516 StringCase(psz, "BASE") ||
517 StringCase(psz, "CODE") ||
518 StringCase(psz, "DATA") ||
519 StringCase(psz, "DESCRIPTION") ||
520 StringCase(psz, "EXETYPE") ||
521 StringCase(psz, "HEAPSIZE") ||
522 StringCase(psz, "OLD") ||
523 StringCase(psz, "STACKSIZE") ||
524 StringCase(psz, "STUB") ||
525 StringCase(psz, "SEGMENTS") ||
526 StringCase(psz, "IMPORTS") ||
527 StringCase(psz, "EXPORTS")
528 );
529}
530
531
532/**
[4402]533 * Extracts the module name from the pszType string.
[824]534 * @returns Success indicator.
535 * @param pszBuffer Pointer to string buffer which is to hold the module name upon return.
536 * @remark Assumes that pszBuffer is large enough.
537 */
[8003]538KBOOL kFileDef::setModuleName(void)
[824]539{
[4402]540 char *pszEnd;
541 char *pszStart;
[824]542
[8003]543 kASSERT(pszType);
[4402]544
545 /* skip the first word */
546 pszStart = strpbrk(pszType, " \t");
547 if (pszStart != NULL)
[824]548 {
[9132]549 /* if phys/virt device skip second word too */
550 if (fVirtualDevice || fPhysicalDevice)
551 {
552 pszStart = strpbrk(ltrim(pszStart), " \t");
553 if (pszStart == NULL)
554 return TRUE;
555 }
556
[4402]557 pszStart = ltrim(pszStart);
558 pszEnd = strpbrk(pszStart, " \t");
559 if (pszEnd == NULL)
[4424]560 pszEnd = pszStart + strlen(pszStart);
[4402]561 pszModName = new char[pszEnd - pszStart + 1];
562 memcpy(pszModName, pszStart, pszEnd - pszStart);
563 pszModName[pszEnd - pszStart] = '\0';
[824]564 }
565 else
[4402]566 return !StringCase(pszType, "LIBRARY");
567 return TRUE;
568}
569
570
571/**
572 * Query for the module name.
[5531]573 * @returns Success indicator. TRUE / FALSE.
574 * @param pszBuffer Pointer to buffer which to put the name into.
575 * @param cchBuffer Size of the buffer (defaults to 260 chars).
[4402]576 */
[8003]577KBOOL kFileDef::moduleGetName(char *pszBuffer, int cchSize/* = 260*/)
[4402]578{
[5531]579 int cch;
[4402]580 if (pszModName == NULL)
[824]581 return FALSE;
[4402]582
[5531]583 cch = strlen(pszModName) + 1;
584 if (cch > cchSize)
585 return FALSE;
586 memcpy(pszBuffer, pszModName, cch);
[4402]587
[824]588 return TRUE;
589}
590
591
592/**
593 * Finds the first exports.
594 * @returns Success indicator. TRUE / FALSE.
595 * @param pExport Pointer to export structure.
596 */
[8003]597KBOOL kFileDef::exportFindFirst(kExportEntry *pExport)
[824]598{
599 if (pExports != NULL && pExport != NULL)
600 {
601 pExport->ulOrdinal = pExports->ulOrdinal;
[5531]602 pExport->achName[0] = '\0';
[824]603 if (pExports->pszName != NULL)
604 strcpy(&pExport->achName[0], pExports->pszName);
[5531]605
606 pExport->achIntName[0] = '\0';
[824]607 if (pExports->pszIntName)
608 strcpy(&pExport->achIntName[0], pExports->pszIntName);
[5531]609
610 pExport->ulAddress = pExport->iObject = pExport->ulOffset = ~0UL;
[824]611 pExport->pv = (void*)pExports->pNext;
612 }
613 else
614 return FALSE;
615 return TRUE;
616}
617
618
619/**
620 * Finds the next export.
621 * @returns Success indicator. TRUE / FALSE.
622 * @param pExport Pointer to export structure.
623 */
[8003]624KBOOL kFileDef::exportFindNext(kExportEntry *pExport)
[824]625{
626 if (pExport != NULL && pExport->pv != NULL)
627 {
628 PDEFEXPORT pExp = (PDEFEXPORT)pExport->pv;
629
630 pExport->ulOrdinal = pExp->ulOrdinal;
[5531]631 pExport->achName[0] = '\0';
[824]632 if (pExp->pszName != NULL)
633 strcpy(&pExport->achName[0], pExp->pszName);
[5531]634 pExport->achIntName[0] = '\0';
[824]635 if (pExp->pszIntName)
636 strcpy(&pExport->achIntName[0], pExp->pszIntName);
[5531]637 pExport->ulAddress = pExport->iObject = pExport->ulOffset = ~0UL;
[824]638 pExport->pv = (void*)pExp->pNext;
639 }
640 else
641 return FALSE;
642 return TRUE;
643}
644
645
[2759]646/**
[5531]647 * Frees resources associated with the communicatin area.
648 * It's not necessary to call this when exportFindNext has return FALSE.
649 * (We don't allocate anything so it's not a problem ;-)
650 * @param pExport Communication area which has been successfully
651 * processed by findFirstExport.
652 */
653void kFileDef::exportFindClose(kExportEntry *pExport)
654{
655 pExport = pExport;
656 return;
657}
658
659
660/**
661 * Lookup information on a spesific export given by ordinal number.
662 * @returns Success indicator.
663 * @param pExport Communication area containing export information
664 * on successful return.
665 * @remark stub
666 */
[8003]667KBOOL kFileDef::exportLookup(unsigned long ulOrdinal, kExportEntry *pExport)
[5531]668{
[8003]669 kASSERT(!"not implemented.");
[5531]670 ulOrdinal = ulOrdinal;
671 pExport = pExport;
672 return FALSE;
673}
674
675/**
676 * Lookup information on a spesific export given by name.
677 * @returns Success indicator.
678 * @param pExport Communication area containing export information
679 * on successful return.
680 * @remark stub
681 */
[8003]682KBOOL kFileDef::exportLookup(const char * pszName, kExportEntry *pExport)
[5531]683{
[8003]684 kASSERT(!"not implemented.");
[5531]685 pszName = pszName;
686 pExport = pExport;
687 return FALSE;
688}
689
690
691/**
[4402]692 * Make a Watcom Linker parameter file addtition of this definition file.
693 * @returns Success indicator.
694 * @param pFile File which we're to write to (append).
695 * Appends at current posistion.
[8360]696 * @param enmOS The target OS of the link operation.
[4402]697 * @sketch
698 * @status
699 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
700 * @remark
701 */
[21916]702KBOOL kFileDef::makeWatcomLinkFileAddtion(kFile *pOut, int enmOS) throw(kError)
[4402]703{
704 PDEFSEGMENT pSeg;
705 PDEFIMPORT pImp;
706 PDEFEXPORT pExp;
[8003]707 pOut->setThrowOnErrors();
[4402]708
709 /*
710 * Write a little remark first to tell that converted stuff starts here.
711 */
[8003]712 pOut->printf("#\n# Directives generated from .DEF-file.\n#\n");
[4402]713
714 /* Format - Module type */
[8360]715 switch (enmOS)
716 {
717 case kFileDef::os2:
718 pOut->printf("FORMAT OS2 LX %s %s %s\n",
719 fLibrary ? "DLL" :
720 (fProgram ? (chAppType == pm ? "PM"
721 : (chAppType == fullscreen ? "FULLSCREEN"
722 : "PMCOMPATIBLE"))
723 : (fVirtualDevice ? "VIRTDEVICE"
724 : "PHYSDEVICE" )),
[9133]725 fLibrary ? (fInitGlobal || (!fInitInstance && !fTermInstance)
726 ? "INITGLOBAL"
727 : "INITINSTANCE")
728 : "",
729 fLibrary ? (fTermGlobal || (!fTermInstance && !fInitInstance)
730 ? "TERMGLOBAL"
731 : "TERMINSTANCE")
732 : "");
[8360]733 break;
[4402]734
[9132]735 case kFileDef::os2v1:
736 pOut->printf("FORMAT OS2 %s %s %s\n",
737 fLibrary ? "DLL" :
738 (fProgram ? (chAppType == pm ? "PM"
739 : (chAppType == fullscreen ? "FULLSCREEN"
740 : "PMCOMPATIBLE"))
741 : (fVirtualDevice ? "VIRTDEVICE"
742 : "PHYSDEVICE" )),
[9133]743 fLibrary ? (fInitGlobal || fTermGlobal ? "INITGLOBAL" /* Not sure how correct these things are! */
744 : "")
745 : "",
746 /*fLibrary ? (fTermGlobal || fInitGlobal ? "TERMGLOBAL"
747 : "")
748 :*/ "");
[9132]749 break;
750
[8360]751 case kFileDef::win32:
752 if (fLibrary)
753 pOut->printf("FORMAT Window NT DLL %s %s\n"
754 "Runtime Windows\n",
755 fLibrary ? (fInitGlobal ? "INITGLOBAL" : "INITINSTANCE") : "",
756 fLibrary ? (fTermGlobal ? "TERMGLOBAL" : "TERMINSTANCE") : "");
757 else
758 pOut->printf("FORMAT Window NT\n"
759 "Runtime %s\n",
760 fProgram ? chAppType == pm ? "Windows" : "Console" : "Native");
761 break;
762 default:
763 return FALSE;
764 }
[4402]765
[8360]766
[4402]767 /* Module name */
768 if (pszModName)
[8003]769 pOut->printf("OPTION MODNAME=%s\n", pszModName);
[4402]770
771 /* Description */
772 if (pszDescription)
[8003]773 pOut->printf("OPTION DESCRIPTION '%s'\n", pszDescription);
[4402]774
775 /* Base */
776 if (pszBase)
[8003]777 pOut->printf("OPTION OFFSET=%s\n", pszBase);
[4402]778
779 /* Stub */
780 if (pszStub)
[8003]781 pOut->printf("OPTION STUB='%s'\n", pszStub);
[4402]782
783 /* Old */
784 if (pszOld)
[8003]785 pOut->printf("OPTION OLDLIBRARY=%s\n", pszOld);
[4402]786
787 /* Protected mode */
[8360]788 if (pszProtmode && (enmOS == kFileDef::os2))
[8003]789 pOut->printf("OPTION PROTMODE\n", pszProtmode);
[4402]790
791 /* Stacksize */
792 if (pszStackSize)
[8003]793 pOut->printf("OPTION STACK=%s\n", pszStackSize);
[4402]794
795 /* HeapSize */
796 if (pszHeapSize)
[8003]797 pOut->printf("OPTION HEAPSIZE=%s\n", pszHeapSize);
[4402]798
799 /* Code - not supported */
800
801 /* Data - not supported */
802
803 /*
804 * Segments.
805 */
806 pSeg = pSegments;
807 while (pSeg != NULL)
808 {
[9162]809 if (pSeg->pszName)
[9164]810 pOut->printf("SEGMENT '%s' %s\n", pSeg->pszName, pSeg->pszAttr ? pSeg->pszAttr : "");
[9162]811 if (pSeg->pszClass)
[9164]812 pOut->printf("SEGMENT CLASS '%s' %s\n", pSeg->pszClass, pSeg->pszAttr ? pSeg->pszAttr : "");
[4402]813 pSeg = pSeg->pNext;
814 }
815
816 /*
817 * Imports.
818 */
819 pImp = pImports;
820 while (pImp != NULL)
821 {
822 if (pImp->pszName == NULL)
[8003]823 pOut->printf("IMPORT '%s' '%s'.%d\n", pImp->pszIntName, pImp->pszDll, pImp->ulOrdinal);
[4402]824 else
[8003]825 pOut->printf("IMPORT '%s' '%s'.'%s'\n", pImp->pszIntName, pImp->pszDll, pImp->pszName);
[4402]826 pImp = pImp->pNext;
827 }
828
829 /*
830 * Exports.
831 */
832 pExp = pExports;
833 while (pExp != NULL)
834 {
[8003]835 pOut->printf("EXPORT '%s'", pExp->pszName);
[4402]836 if (pExp->ulOrdinal != ~0UL)
[8003]837 pOut->printf(".%d", pExp->ulOrdinal);
[4402]838 if (pExp->pszIntName)
[8003]839 pOut->printf("='%s'", pExp->pszIntName);
[8360]840 if (pExp->fResident && (enmOS == kFileDef::os2 || enmOS == kFileDef::win16))
[8003]841 pOut->printf(" RESIDENT");
[4402]842 if (pExp->cParam != ~0UL)
[8003]843 pOut->printf(" %d", pExp->cParam * 2); /* .DEFs this is number of words. Watcom should have bytes. */
844 pOut->printf("\n");
[4402]845 pExp = pExp->pNext;
846 }
847
848 return TRUE;
849}
850
851
852
853
854/**
[2759]855 * Removes '"' and ''' at start and end of the string.
856 * @returns pszStr!
857 * @param pszStr String that is to have "s and 's removed.
858 */
859static char *removeFnutts(char *pszStr)
860{
861 if (pszStr != NULL)
862 {
863 int cch = strlen(pszStr);
864 if (cch > 0 && (pszStr[cch-1] == '"' || pszStr[cch-1] == '\''))
865 pszStr[cch-1] = '\0';
866
867 if (*pszStr == '"' || *pszStr == '\'')
868 memmove(pszStr, pszStr+1, cch-1);
869 }
870 return pszStr;
871}
[4402]872
873
874/**
875 * Upcases a char.
876 * @returns Upper case of the char given in ch.
877 * @param ch Char to capitalize.
878 */
879inline char upcase(char ch)
880{
881 return ch >= 'a' && ch <= 'z' ? (char)(ch - ('a' - 'A')) : ch;
882}
883
884
885/**
886 * Searches for a substring in a string.
887 * @returns Pointer to start of substring when found, NULL when not found.
888 * @param pszStr String to be searched.
889 * @param pszSubStr String to be searched.
890 * @remark Depends on the upcase function.
891 */
892static char *stristr(const char *pszStr, const char *pszSubStr)
893{
894 int cchSubStr = strlen(pszSubStr);
895 int i = 0;
896
897 while (*pszStr != '\0' && i < cchSubStr)
898 {
899 i = 0;
900 while (i < cchSubStr && pszStr[i] != '\0' &&
901 (upcase(pszStr[i]) == upcase(pszSubStr[i])))
902 i++;
903 pszStr++;
904 }
905
906 return (char*)(*pszStr != '\0' ? pszStr - 1 : NULL);
907}
908
Note: See TracBrowser for help on using the repository browser.