1 | /*
|
---|
2 | *@@sourcefile map_vac.c:
|
---|
3 | * map file parser for the VAC 3.08 format.
|
---|
4 | *
|
---|
5 | * Usage: All OS/2 programs.
|
---|
6 | *
|
---|
7 | * Note: Version numbering in this file relates to XWorkplace version
|
---|
8 | * numbering.
|
---|
9 | *
|
---|
10 | *@@added V1.0.0 (2002-09-13) [umoeller]
|
---|
11 | *
|
---|
12 | *@@header "helpers\mapfile.h"
|
---|
13 | */
|
---|
14 |
|
---|
15 | /*
|
---|
16 | * This file Copyright (C) 2002 Ulrich Mller.
|
---|
17 | * This file is part of the "XWorkplace helpers" source package.
|
---|
18 | * This is free software; you can redistribute it and/or modify
|
---|
19 | * it under the terms of the GNU General Public License as published
|
---|
20 | * by the Free Software Foundation, in version 2 as it comes in the
|
---|
21 | * "COPYING" file of the XWorkplace main distribution.
|
---|
22 | * This program is distributed in the hope that it will be useful,
|
---|
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
25 | * GNU General Public License for more details.
|
---|
26 | */
|
---|
27 |
|
---|
28 | #define OS2EMX_PLAIN_CHAR
|
---|
29 | // this is needed for "os2emx.h"; if this is defined,
|
---|
30 | // emx will define PSZ as _signed_ char, otherwise
|
---|
31 | // as unsigned char
|
---|
32 |
|
---|
33 | #define INCL_DOSPROCESS
|
---|
34 | #define INCL_DOSMODULEMGR
|
---|
35 | #define INCL_DOSMISC
|
---|
36 | #define INCL_DOSERRORS
|
---|
37 | #include <os2.h>
|
---|
38 |
|
---|
39 | #include <stdlib.h>
|
---|
40 | #include <stdio.h>
|
---|
41 | #include <string.h>
|
---|
42 |
|
---|
43 | #define DONT_REPLACE_MALLOC
|
---|
44 | #include "setup.h" // code generation and debugging options
|
---|
45 |
|
---|
46 | #include "helpers\linklist.h"
|
---|
47 | #include "helpers\mapfile.h"
|
---|
48 | #include "helpers\stringh.h"
|
---|
49 | #include "helpers\standards.h"
|
---|
50 |
|
---|
51 | #pragma hdrstop
|
---|
52 |
|
---|
53 | /*
|
---|
54 | *@@category: Helpers\Control program helpers\Map file parsing (VAC 3.08)
|
---|
55 | * See map_vac.c.
|
---|
56 | */
|
---|
57 |
|
---|
58 | /*
|
---|
59 | *@@ MAPSTATE:
|
---|
60 | *
|
---|
61 | */
|
---|
62 |
|
---|
63 | typedef enum _MAPSTATE
|
---|
64 | {
|
---|
65 | MAP_START,
|
---|
66 | // until we find " Start Length Name Class"
|
---|
67 |
|
---|
68 | MAP_SEGMENTS,
|
---|
69 | // each segment is introduced by
|
---|
70 | // " 0001:00000000 000001630H FREQ_CODE1 CODE 32-bit"
|
---|
71 | // then for each source file
|
---|
72 | // " at offset 00000000 003A4H bytes from T:\_build\xwp\xfdataf.obj (xfdataf.c)"
|
---|
73 |
|
---|
74 | // until we find " Origin Group"
|
---|
75 |
|
---|
76 | MAP_GROUPS,
|
---|
77 | // whatever this is for, ignoring for now
|
---|
78 | // until we find " Address Export Alias"
|
---|
79 |
|
---|
80 | MAP_EXPORTS,
|
---|
81 | // for each export
|
---|
82 | // " 0003:00096AE8 apmhClose apmhClose"
|
---|
83 |
|
---|
84 | // until we find
|
---|
85 | // " Address Publics by Name"
|
---|
86 |
|
---|
87 | MAP_PUBLICS_BY_NAME,
|
---|
88 | // for each public
|
---|
89 | // " 0003:000A800A anmBlowUpBitmap"
|
---|
90 | // or, for imports,
|
---|
91 | // " 0000:00000000 Imp DevCloseDC (PMGPI.604)"
|
---|
92 |
|
---|
93 | // until we find
|
---|
94 | // " Address Publics by Value"
|
---|
95 |
|
---|
96 | MAP_PUBLICS_BY_VALUE,
|
---|
97 | // same thing as previous section, we can ignore that
|
---|
98 |
|
---|
99 | // until we find
|
---|
100 | // "Line numbers for T:\_build\xwp\xcenter.obj(xcenter.c)"
|
---|
101 |
|
---|
102 | MAP_LINENUMBERS_FILEINTRO,
|
---|
103 |
|
---|
104 | // starts with:
|
---|
105 | // " Record Number of Start of Source: 0"
|
---|
106 | // " Number of Primary Source Records: 0"
|
---|
107 | // " Source & Listing Files: 67"
|
---|
108 |
|
---|
109 | // then
|
---|
110 | // " File 1) xcenter.c" etc.
|
---|
111 |
|
---|
112 | // until we find
|
---|
113 | // "Line numbers for T:\_build\xwp\xcenter.obj(xcenter.c) segment CODE32 (@0x00000000)"
|
---|
114 |
|
---|
115 | MAP_LINENUMBERS_FILEDATA,
|
---|
116 |
|
---|
117 | // starts with:
|
---|
118 | // " Source Src File Seg:Offset
|
---|
119 | // " Line Num Index (0X)
|
---|
120 | // " -------- -------- -------------
|
---|
121 |
|
---|
122 | // then for each line
|
---|
123 | // " 1630 1 0003:00000000"
|
---|
124 |
|
---|
125 | // until we find again
|
---|
126 | // "Line numbers for T:\_build\xwp\xcenter.obj(xcenter.c)"
|
---|
127 |
|
---|
128 | // or
|
---|
129 | // "Program entry point at 0003:00023228"
|
---|
130 |
|
---|
131 | } MAPSTATE;
|
---|
132 |
|
---|
133 | /*
|
---|
134 | *@@ mapvRead:
|
---|
135 | *
|
---|
136 | */
|
---|
137 |
|
---|
138 | APIRET mapvRead(PCSZ pcszMapFilename,
|
---|
139 | PMAPFILE *ppMapFile,
|
---|
140 | PSZ pszLineBuf,
|
---|
141 | ULONG cbLineBuf,
|
---|
142 | PULONG pulLineError) // out: line no. where we choked
|
---|
143 | {
|
---|
144 | APIRET arc = NO_ERROR;
|
---|
145 | ULONG ulLine = 2;
|
---|
146 |
|
---|
147 | MAPSTATE State = MAP_START;
|
---|
148 |
|
---|
149 | PMAPFILE pMapFile = NULL;
|
---|
150 | PSEGMENT pCurrentSegment = NULL;
|
---|
151 |
|
---|
152 | FILE *MapFile;
|
---|
153 |
|
---|
154 | if (!(MapFile = fopen(pcszMapFilename, "r")))
|
---|
155 | return _doserrno;
|
---|
156 |
|
---|
157 | while (!arc)
|
---|
158 | {
|
---|
159 | if (!(fgets(pszLineBuf, cbLineBuf, MapFile)))
|
---|
160 | {
|
---|
161 | if (!(feof(MapFile)))
|
---|
162 | arc = _doserrno;
|
---|
163 |
|
---|
164 | break;
|
---|
165 | }
|
---|
166 |
|
---|
167 | // printf("Running line \"%s\"", pszLineBuf);
|
---|
168 |
|
---|
169 | ulLine++;
|
---|
170 |
|
---|
171 | if ( (pszLineBuf[0] == '\n')
|
---|
172 | || (pszLineBuf[0] == '\r')
|
---|
173 | )
|
---|
174 | // empty line:
|
---|
175 | continue;
|
---|
176 |
|
---|
177 | #define STRNCMP(p1, p2) memcmp(p1, p2, sizeof(p2) - 1)
|
---|
178 |
|
---|
179 | switch (State)
|
---|
180 | {
|
---|
181 | case MAP_START:
|
---|
182 | if (!STRNCMP(pszLineBuf,
|
---|
183 | " Start Length Name Class"))
|
---|
184 | {
|
---|
185 | if (!pMapFile)
|
---|
186 | arc = MAPERROR_NO_MODULE_NAME;
|
---|
187 | else
|
---|
188 | State = MAP_SEGMENTS;
|
---|
189 | }
|
---|
190 | else
|
---|
191 | {
|
---|
192 | PSZ p = pszLineBuf;
|
---|
193 | while (*p == ' ')
|
---|
194 | p++;
|
---|
195 | if (*p)
|
---|
196 | {
|
---|
197 | if (!(pMapFile = NEW(MAPFILE)))
|
---|
198 | arc = ERROR_NOT_ENOUGH_MEMORY;
|
---|
199 | else
|
---|
200 | {
|
---|
201 | ZERO(pMapFile);
|
---|
202 | strncpy(pMapFile->szModule,
|
---|
203 | p,
|
---|
204 | strchr(p, '\n') - p);
|
---|
205 |
|
---|
206 | lstInit(&pMapFile->llSegments, TRUE);
|
---|
207 | lstInit(&pMapFile->llExports, TRUE);
|
---|
208 | lstInit(&pMapFile->llPublics, TRUE);
|
---|
209 | }
|
---|
210 | }
|
---|
211 | else
|
---|
212 | return MAPERROR_NO_MODULE_NAME;
|
---|
213 | }
|
---|
214 | break;
|
---|
215 |
|
---|
216 | case MAP_SEGMENTS:
|
---|
217 | if (!STRNCMP(pszLineBuf,
|
---|
218 | " Origin Group"))
|
---|
219 | {
|
---|
220 | pCurrentSegment = NULL;
|
---|
221 |
|
---|
222 | State = MAP_GROUPS;
|
---|
223 | }
|
---|
224 | else if (!STRNCMP(pszLineBuf,
|
---|
225 | "\tat offset "))
|
---|
226 | {
|
---|
227 |
|
---|
228 | }
|
---|
229 | // " 0001:00000000 000001630H FREQ_CODE1 CODE 32-bit"
|
---|
230 | else if ( (pszLineBuf[0] == ' ')
|
---|
231 | && (pszLineBuf[5] == ':')
|
---|
232 | )
|
---|
233 | {
|
---|
234 | if (!(pCurrentSegment = NEW(SEGMENT)))
|
---|
235 | arc = ERROR_NOT_ENOUGH_MEMORY;
|
---|
236 | else
|
---|
237 | {
|
---|
238 | ZERO(pCurrentSegment);
|
---|
239 |
|
---|
240 | if (3 != sscanf(pszLineBuf,
|
---|
241 | " %04lX:%08lX %08lXH ",
|
---|
242 | &pCurrentSegment->ulObjNo,
|
---|
243 | &pCurrentSegment->ulObjOfs,
|
---|
244 | &pCurrentSegment->cbSeg))
|
---|
245 | {
|
---|
246 | arc = MAPERROR_SYNTAX_SEGMENTS_START;
|
---|
247 | }
|
---|
248 | else
|
---|
249 | {
|
---|
250 | PSZ pStartOfSegName = pszLineBuf + sizeof(" 0001:00000000 000001630H ") - 1;
|
---|
251 | PSZ pSpaceAfterSegName;
|
---|
252 |
|
---|
253 | if (!(pSpaceAfterSegName = strchr(pStartOfSegName, ' ')))
|
---|
254 | arc = MAPERROR_SYNTAX_SEGMENTS_NOSEGNAME;
|
---|
255 | else
|
---|
256 | {
|
---|
257 | PSZ pStartOfSegType;
|
---|
258 | memcpy(pCurrentSegment->szSegName,
|
---|
259 | pStartOfSegName,
|
---|
260 | pSpaceAfterSegName - pStartOfSegName);
|
---|
261 |
|
---|
262 | pStartOfSegType = pszLineBuf + sizeof(" 0006:00000000 00001E288H CONST32_RO ") - 1;
|
---|
263 | if (!STRNCMP(pStartOfSegType,
|
---|
264 | "CODE 32-bit"))
|
---|
265 | pCurrentSegment->ulType = SEGTYPE_CODE32;
|
---|
266 | else if (!STRNCMP(pStartOfSegType,
|
---|
267 | "CODE 16-bit"))
|
---|
268 | pCurrentSegment->ulType = SEGTYPE_CODE16;
|
---|
269 | else if (!STRNCMP(pStartOfSegType,
|
---|
270 | "CONST 32-bit"))
|
---|
271 | pCurrentSegment->ulType = SEGTYPE_CONST32;
|
---|
272 | else if (!STRNCMP(pStartOfSegType,
|
---|
273 | "DATA16 16-bit"))
|
---|
274 | pCurrentSegment->ulType = SEGTYPE_DATA16;
|
---|
275 | else if (!STRNCMP(pStartOfSegType,
|
---|
276 | "DATA 32-bit"))
|
---|
277 | pCurrentSegment->ulType = SEGTYPE_DATA32;
|
---|
278 | else if (!STRNCMP(pStartOfSegType,
|
---|
279 | "EDC_CLASS 32-bit"))
|
---|
280 | pCurrentSegment->ulType = SEGTYPE_EDC_CLASS32;
|
---|
281 | else if (!STRNCMP(pStartOfSegType,
|
---|
282 | "BSS 32-bit"))
|
---|
283 | pCurrentSegment->ulType = SEGTYPE_BSS32;
|
---|
284 | else if (!STRNCMP(pStartOfSegType,
|
---|
285 | "STACK 32-bit"))
|
---|
286 | pCurrentSegment->ulType = SEGTYPE_STACK32;
|
---|
287 | else
|
---|
288 | {
|
---|
289 | printf(" MAP_SEGMENTS: Cannot handle segment type \"%s\"",
|
---|
290 | pStartOfSegType);
|
---|
291 | arc = MAPERROR_SYNTAX_SEGMENTS_SEGTYPE;
|
---|
292 | }
|
---|
293 | }
|
---|
294 |
|
---|
295 | if (!arc)
|
---|
296 | lstAppendItem(&pMapFile->llSegments,
|
---|
297 | pCurrentSegment);
|
---|
298 | else
|
---|
299 | FREE(pCurrentSegment);
|
---|
300 | }
|
---|
301 | }
|
---|
302 | }
|
---|
303 | else
|
---|
304 | arc = MAPERROR_SYNTAX_SEGMENTS_OTHER;
|
---|
305 | break;
|
---|
306 |
|
---|
307 | case MAP_GROUPS:
|
---|
308 | if (!STRNCMP(pszLineBuf,
|
---|
309 | " Address Export Alias"))
|
---|
310 | {
|
---|
311 | State = MAP_EXPORTS;
|
---|
312 | }
|
---|
313 | // executables usually have no exports, so we
|
---|
314 | // might run into the publics as well
|
---|
315 | else if (!STRNCMP(pszLineBuf,
|
---|
316 | " Address Publics by Name"))
|
---|
317 | {
|
---|
318 | State = MAP_PUBLICS_BY_NAME;
|
---|
319 | }
|
---|
320 | break;
|
---|
321 |
|
---|
322 | case MAP_EXPORTS:
|
---|
323 | if (!STRNCMP(pszLineBuf,
|
---|
324 | " Address Publics by Name"))
|
---|
325 | {
|
---|
326 | State = MAP_PUBLICS_BY_NAME;
|
---|
327 | }
|
---|
328 | // " 0003:00096AE8 apmhClose apmhClose"
|
---|
329 | else if ( (pszLineBuf[0] == ' ')
|
---|
330 | && (pszLineBuf[5] == ':')
|
---|
331 | )
|
---|
332 | {
|
---|
333 | EXPORT expTemp;
|
---|
334 |
|
---|
335 | if (2 != sscanf(pszLineBuf,
|
---|
336 | " %04lX:%08lX ",
|
---|
337 | &expTemp.ulObjNo,
|
---|
338 | &expTemp.ulObjOfs))
|
---|
339 | arc = MAPERROR_SYNTAX_EXPORTS_OBJOFS;
|
---|
340 | else
|
---|
341 | {
|
---|
342 | PSZ pStartOfName1 = pszLineBuf + sizeof(" 0003:00096AE8 ") - 1,
|
---|
343 | pEndOfName1;
|
---|
344 | if (!(pEndOfName1 = strchr(pStartOfName1, ' ')))
|
---|
345 | arc = MAPERROR_SYNTAX_EXPORTS_NAME1;
|
---|
346 | else
|
---|
347 | {
|
---|
348 | PSZ pStartOfName2 = pEndOfName1,
|
---|
349 | pEndOfName2;
|
---|
350 |
|
---|
351 | PEXPORT pExport;
|
---|
352 |
|
---|
353 | while (*pStartOfName2 == ' ')
|
---|
354 | pStartOfName2++;
|
---|
355 | pEndOfName2 = strhFindEOL(pStartOfName2, NULL);
|
---|
356 |
|
---|
357 | expTemp.ulName1Len = pEndOfName1 - pStartOfName1;
|
---|
358 | expTemp.ulName2Len = pEndOfName2 - pStartOfName2;
|
---|
359 |
|
---|
360 | if (!(pExport = malloc( sizeof(EXPORT)
|
---|
361 | + expTemp.ulName1Len
|
---|
362 | + expTemp.ulName2Len
|
---|
363 | + 1
|
---|
364 | )))
|
---|
365 | arc = ERROR_NOT_ENOUGH_MEMORY;
|
---|
366 | else
|
---|
367 | {
|
---|
368 | PSZ pszName2;
|
---|
369 | memcpy(pExport,
|
---|
370 | &expTemp,
|
---|
371 | sizeof(expTemp));
|
---|
372 | memcpy(pExport->szNames,
|
---|
373 | pStartOfName1,
|
---|
374 | expTemp.ulName1Len);
|
---|
375 | pExport->szNames[expTemp.ulName1Len] = '\0';
|
---|
376 |
|
---|
377 | pszName2 = pExport->szNames +expTemp.ulName1Len + 1;
|
---|
378 | memcpy(pszName2,
|
---|
379 | pStartOfName2,
|
---|
380 | expTemp.ulName2Len);
|
---|
381 | pszName2[expTemp.ulName2Len] = '\0';
|
---|
382 |
|
---|
383 | lstAppendItem(&pMapFile->llExports, pExport);
|
---|
384 | }
|
---|
385 | }
|
---|
386 | }
|
---|
387 | }
|
---|
388 | else
|
---|
389 | arc = MAPERROR_SYNTAX_EXPORTS_OTHER;
|
---|
390 | break;
|
---|
391 |
|
---|
392 | case MAP_PUBLICS_BY_NAME:
|
---|
393 | if (!STRNCMP(pszLineBuf,
|
---|
394 | " Address Publics by Value"))
|
---|
395 | {
|
---|
396 | State = MAP_PUBLICS_BY_VALUE;
|
---|
397 | }
|
---|
398 | // " 0003:00096AE8 apmhClose apmhClose"
|
---|
399 | else if ( (pszLineBuf[0] == ' ')
|
---|
400 | && (pszLineBuf[5] == ':')
|
---|
401 | )
|
---|
402 | {
|
---|
403 | PUBLIC pubTemp;
|
---|
404 |
|
---|
405 | if (2 != sscanf(pszLineBuf,
|
---|
406 | " %04lX:%08lX ",
|
---|
407 | &pubTemp.ulObjNo,
|
---|
408 | &pubTemp.ulObjOfs))
|
---|
409 | arc = MAPERROR_SYNTAX_PUBLICS_OBJOFS;
|
---|
410 | else
|
---|
411 | {
|
---|
412 | PSZ p2 = pszLineBuf + sizeof(" 0000:00000000 ") - 1,
|
---|
413 | p3;
|
---|
414 | PPUBLIC pPublic;
|
---|
415 | PCSZ pcszImportLib = NULL;
|
---|
416 |
|
---|
417 | BOOL fImport = !STRNCMP(p2, "Imp");
|
---|
418 |
|
---|
419 | p2 += 5;
|
---|
420 |
|
---|
421 | pubTemp.ulImportLen = 0;
|
---|
422 | pubTemp.ulImportIndex = 0;
|
---|
423 |
|
---|
424 | if (fImport)
|
---|
425 | {
|
---|
426 | p3 = strchr(p2, ' ');
|
---|
427 | pubTemp.ulNameLen = p3 - p2;
|
---|
428 | if (p3 = strchr(p3, '('))
|
---|
429 | {
|
---|
430 | PSZ p4;
|
---|
431 | pcszImportLib = p3 + 1;
|
---|
432 | p4 = strchr(pcszImportLib, '.');
|
---|
433 | // "(DOSCALLS.303)"
|
---|
434 | pubTemp.ulImportLen = p4 - pcszImportLib;
|
---|
435 | pubTemp.ulImportIndex = atoi(p4 + 1);
|
---|
436 | }
|
---|
437 | }
|
---|
438 | else
|
---|
439 | // no import:
|
---|
440 | p3 = strhFindEOL(p2, &pubTemp.ulNameLen);
|
---|
441 |
|
---|
442 | if (!(pPublic = malloc( sizeof(PUBLIC)
|
---|
443 | + pubTemp.ulNameLen
|
---|
444 | + pubTemp.ulImportLen
|
---|
445 | + 1)))
|
---|
446 | arc = ERROR_NOT_ENOUGH_MEMORY;
|
---|
447 | else
|
---|
448 | {
|
---|
449 | memcpy(pPublic, &pubTemp, sizeof(PUBLIC));
|
---|
450 | memcpy(pPublic->szName,
|
---|
451 | p2,
|
---|
452 | pubTemp.ulNameLen);
|
---|
453 | pPublic->szName[pubTemp.ulNameLen] = '\0';
|
---|
454 |
|
---|
455 | if (pubTemp.ulImportLen)
|
---|
456 | {
|
---|
457 | PSZ pszImport = pPublic->szName + pubTemp.ulNameLen + 1;
|
---|
458 | memcpy(pszImport,
|
---|
459 | pcszImportLib,
|
---|
460 | pubTemp.ulImportLen);
|
---|
461 | pszImport[pubTemp.ulImportLen] = '\0';
|
---|
462 | }
|
---|
463 |
|
---|
464 |
|
---|
465 | lstAppendItem(&pMapFile->llPublics, pPublic);
|
---|
466 | }
|
---|
467 | }
|
---|
468 | }
|
---|
469 | else
|
---|
470 | arc = MAPERROR_SYNTAX_PUBLICS_OTHER;
|
---|
471 | break;
|
---|
472 |
|
---|
473 | case MAP_PUBLICS_BY_VALUE:
|
---|
474 | if (!STRNCMP(pszLineBuf,
|
---|
475 | "Line numbers for "))
|
---|
476 | {
|
---|
477 | // "Line numbers for T:\_build\xwp\xcenter.obj(xcenter.c)"
|
---|
478 | PSZ pObjStart,
|
---|
479 | pSourceStart,
|
---|
480 | pSourceEnd;
|
---|
481 |
|
---|
482 | StartLineNumersIntro:
|
---|
483 |
|
---|
484 | pObjStart = pszLineBuf + sizeof("Line numbers for ") - 1;
|
---|
485 | if (pSourceStart = strchr(pObjStart, '('))
|
---|
486 | {
|
---|
487 | *pSourceStart++ = '\0';
|
---|
488 | if (pSourceEnd = strchr(pSourceStart, ')'))
|
---|
489 | *pSourceEnd = '\0';
|
---|
490 | }
|
---|
491 |
|
---|
492 | // starts with:
|
---|
493 | // " Record Number of Start of Source: 0"
|
---|
494 | // " Number of Primary Source Records: 0"
|
---|
495 | // " Source & Listing Files: 67"
|
---|
496 |
|
---|
497 |
|
---|
498 | State = MAP_LINENUMBERS_FILEINTRO;
|
---|
499 | }
|
---|
500 | break;
|
---|
501 |
|
---|
502 | case MAP_LINENUMBERS_FILEINTRO:
|
---|
503 | if (!STRNCMP(pszLineBuf,
|
---|
504 | "Line numbers for "))
|
---|
505 | {
|
---|
506 | State = MAP_LINENUMBERS_FILEDATA;
|
---|
507 | }
|
---|
508 | break;
|
---|
509 |
|
---|
510 | case MAP_LINENUMBERS_FILEDATA:
|
---|
511 | if (!STRNCMP(pszLineBuf,
|
---|
512 | "Program entry point at "))
|
---|
513 | {
|
---|
514 | break;
|
---|
515 | }
|
---|
516 | else if (!STRNCMP(pszLineBuf,
|
---|
517 | "Line numbers for "))
|
---|
518 | {
|
---|
519 | goto StartLineNumersIntro;
|
---|
520 | }
|
---|
521 | break;
|
---|
522 |
|
---|
523 | default:
|
---|
524 | printf("Internal error, unknown parsing state.\n");
|
---|
525 | break;
|
---|
526 | }
|
---|
527 | }
|
---|
528 |
|
---|
529 | if (arc)
|
---|
530 | {
|
---|
531 | mapvClose(&pMapFile);
|
---|
532 | *pulLineError = ulLine;
|
---|
533 | }
|
---|
534 | else
|
---|
535 | *ppMapFile = pMapFile;
|
---|
536 |
|
---|
537 | fclose(MapFile);
|
---|
538 |
|
---|
539 | return arc;
|
---|
540 | }
|
---|
541 |
|
---|
542 | /*
|
---|
543 | *@@ mapvClose:
|
---|
544 | *
|
---|
545 | */
|
---|
546 |
|
---|
547 | APIRET mapvClose(PMAPFILE *ppMapFile)
|
---|
548 | {
|
---|
549 | PMAPFILE pMapFile;
|
---|
550 |
|
---|
551 | if ( (!ppMapFile)
|
---|
552 | || (!(pMapFile = *ppMapFile))
|
---|
553 | )
|
---|
554 | return ERROR_INVALID_PARAMETER;
|
---|
555 |
|
---|
556 | // these three are auto-free
|
---|
557 | lstClear(&pMapFile->llSegments);
|
---|
558 | lstClear(&pMapFile->llExports);
|
---|
559 | lstClear(&pMapFile->llPublics);
|
---|
560 |
|
---|
561 | free(pMapFile);
|
---|
562 | *ppMapFile = NULL;
|
---|
563 | }
|
---|