Root/
Source at commit 284 created 13 years 10 months ago. By blackosx, Amended my mistake by updating the Default theme images in the trunk. Now put them back as they were.. (Sorry) | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * Portions Copyright (c) 2003 Apple Computer, Inc. All Rights␊ |
7 | * Reserved. ␊ |
8 | * The contents of this file constitute Original Code as defined in and␊ |
9 | * are subject to the Apple Public Source License Version 2.0 (the␊ |
10 | * "License"). You may not use this file except in compliance with the␊ |
11 | * License. Please obtain a copy of the License at␊ |
12 | * http://www.apple.com/publicsource and read it before using this file.␊ |
13 | * ␊ |
14 | * This Original Code and all software distributed under the License are␊ |
15 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the␊ |
19 | * License for the specific language governing rights and limitations␊ |
20 | * under the License.␊ |
21 | * ␊ |
22 | * @APPLE_LICENSE_HEADER_END@␊ |
23 | */␊ |
24 | ␊ |
25 | #include "bootstruct.h"␊ |
26 | #include "libsaio.h"␊ |
27 | #include "sl.h"␊ |
28 | #include "xml.h"␊ |
29 | ␊ |
30 | struct Module { ␊ |
31 | struct Module *nextModule;␊ |
32 | long willLoad;␊ |
33 | TagPtr dict;␊ |
34 | char *plistAddr;␊ |
35 | long plistLength;␊ |
36 | char *driverPath;␊ |
37 | };␊ |
38 | typedef struct Module Module, *ModulePtr;␊ |
39 | ␊ |
40 | struct DriverInfo {␊ |
41 | char *plistAddr;␊ |
42 | long plistLength;␊ |
43 | void *moduleAddr;␊ |
44 | long moduleLength;␊ |
45 | };␊ |
46 | typedef struct DriverInfo DriverInfo, *DriverInfoPtr;␊ |
47 | ␊ |
48 | #define kDriverPackageSignature1 'MKXT'␊ |
49 | #define kDriverPackageSignature2 'MOSX'␊ |
50 | ␊ |
51 | struct DriversPackage {␊ |
52 | unsigned long signature1;␊ |
53 | unsigned long signature2;␊ |
54 | unsigned long length;␊ |
55 | unsigned long alder32;␊ |
56 | unsigned long version;␊ |
57 | unsigned long numDrivers;␊ |
58 | unsigned long reserved1;␊ |
59 | unsigned long reserved2;␊ |
60 | };␊ |
61 | typedef struct DriversPackage DriversPackage;␊ |
62 | ␊ |
63 | enum {␊ |
64 | kCFBundleType2,␊ |
65 | kCFBundleType3␊ |
66 | };␊ |
67 | ␊ |
68 | ␊ |
69 | #define USEMALLOC 1␊ |
70 | #define DOFREE 1␊ |
71 | ␊ |
72 | static long ParseTagList(char *buffer, TagPtr *tag, long type, long empty);␊ |
73 | static long ParseTagKey(char *buffer, TagPtr *tag);␊ |
74 | static long ParseTagString(char *buffer, TagPtr *tag);␊ |
75 | static long ParseTagInteger(char *buffer, TagPtr *tag);␊ |
76 | static long ParseTagData(char *buffer, TagPtr *tag);␊ |
77 | static long ParseTagDate(char *buffer, TagPtr *tag);␊ |
78 | static long ParseTagBoolean(char *buffer, TagPtr *tag, long type);␊ |
79 | static long GetNextTag(char *buffer, char **tag, long *start);␊ |
80 | static long FixDataMatchingTag(char *buffer, char *tag);␊ |
81 | static TagPtr NewTag(void);␊ |
82 | static char *NewSymbol(char *string);␊ |
83 | #if DOFREE␊ |
84 | static void FreeSymbol(char *string);␊ |
85 | #endif␊ |
86 | ␊ |
87 | ␊ |
88 | //==========================================================================␊ |
89 | // XMLGetProperty␊ |
90 | ␊ |
91 | TagPtr␊ |
92 | XMLGetProperty( TagPtr dict, const char * key )␊ |
93 | {␊ |
94 | TagPtr tagList, tag;␊ |
95 | ␊ |
96 | if (dict->type != kTagTypeDict) return 0;␊ |
97 | ␊ |
98 | tag = 0;␊ |
99 | tagList = dict->tag;␊ |
100 | while (tagList)␊ |
101 | {␊ |
102 | tag = tagList;␊ |
103 | tagList = tag->tagNext;␊ |
104 | ␊ |
105 | if ((tag->type != kTagTypeKey) || (tag->string == 0)) continue;␊ |
106 | ␊ |
107 | if (!strcmp(tag->string, key)) return tag->tag;␊ |
108 | }␊ |
109 | ␊ |
110 | return 0;␊ |
111 | }␊ |
112 | ␊ |
113 | ␊ |
114 | #if UNUSED␊ |
115 | //==========================================================================␊ |
116 | // XMLParseFile␊ |
117 | // Expects to see one dictionary in the XML file.␊ |
118 | // Puts the first dictionary it finds in the␊ |
119 | // tag pointer and returns 0, or returns -1 if not found.␊ |
120 | //␊ |
121 | long␊ |
122 | XMLParseFile( char * buffer, TagPtr * dict )␊ |
123 | {␊ |
124 | long length, pos;␊ |
125 | TagPtr tag;␊ |
126 | pos = 0;␊ |
127 | ␊ |
128 | while (1)␊ |
129 | {␊ |
130 | length = XMLParseNextTag(buffer + pos, &tag);␊ |
131 | if (length == -1) break;␊ |
132 | ␊ |
133 | pos += length;␊ |
134 | ␊ |
135 | if (tag == 0) continue;␊ |
136 | if (tag->type == kTagTypeDict) break;␊ |
137 | ␊ |
138 | XMLFreeTag(tag);␊ |
139 | }␊ |
140 | if (length < 0) {␊ |
141 | return -1;␊ |
142 | }␊ |
143 | *dict = tag;␊ |
144 | return 0;␊ |
145 | }␊ |
146 | #endif /* UNUSED */␊ |
147 | ␊ |
148 | //==========================================================================␊ |
149 | // ParseNextTag␊ |
150 | ␊ |
151 | long␊ |
152 | XMLParseNextTag( char * buffer, TagPtr * tag )␊ |
153 | {␊ |
154 | ␉long length, pos;␊ |
155 | ␉char * tagName;␊ |
156 | ␊ |
157 | length = GetNextTag(buffer, &tagName, 0);␊ |
158 | if (length == -1) return -1;␊ |
159 | ␊ |
160 | ␉pos = length;␊ |
161 | if (!strncmp(tagName, kXMLTagPList, 6))␊ |
162 | {␊ |
163 | length = 0;␊ |
164 | }␊ |
165 | else if (!strcmp(tagName, kXMLTagDict))␊ |
166 | {␊ |
167 | length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0);␊ |
168 | }␊ |
169 | else if (!strcmp(tagName, kXMLTagDict "/"))␊ |
170 | {␊ |
171 | length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1);␊ |
172 | }␊ |
173 | else if (!strcmp(tagName, kXMLTagKey))␊ |
174 | {␊ |
175 | length = ParseTagKey(buffer + pos, tag);␊ |
176 | }␊ |
177 | else if (!strcmp(tagName, kXMLTagString))␊ |
178 | {␊ |
179 | length = ParseTagString(buffer + pos, tag);␊ |
180 | }␊ |
181 | else if (!strcmp(tagName, kXMLTagInteger))␊ |
182 | {␊ |
183 | length = ParseTagInteger(buffer + pos, tag);␊ |
184 | }␊ |
185 | else if (!strcmp(tagName, kXMLTagData))␊ |
186 | {␊ |
187 | length = ParseTagData(buffer + pos, tag);␊ |
188 | }␊ |
189 | else if (!strcmp(tagName, kXMLTagDate))␊ |
190 | {␊ |
191 | length = ParseTagDate(buffer + pos, tag);␊ |
192 | }␊ |
193 | else if (!strcmp(tagName, kXMLTagFalse))␊ |
194 | {␊ |
195 | length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse);␊ |
196 | }␊ |
197 | else if (!strcmp(tagName, kXMLTagTrue))␊ |
198 | {␊ |
199 | length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue);␊ |
200 | }␊ |
201 | else if (!strcmp(tagName, kXMLTagArray))␊ |
202 | {␊ |
203 | length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0);␊ |
204 | }␊ |
205 | else if (!strcmp(tagName, kXMLTagArray "/"))␊ |
206 | {␊ |
207 | length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1);␊ |
208 | }␊ |
209 | else␊ |
210 | {␊ |
211 | *tag = 0;␊ |
212 | length = 0;␊ |
213 | }␊ |
214 | ␊ |
215 | if (length == -1) return -1;␊ |
216 | ␊ |
217 | return pos + length;␊ |
218 | }␊ |
219 | ␊ |
220 | //==========================================================================␊ |
221 | // ParseTagList␊ |
222 | ␊ |
223 | static long␊ |
224 | ParseTagList( char * buffer, TagPtr * tag, long type, long empty )␊ |
225 | {␊ |
226 | ␉long length, pos;␊ |
227 | ␉TagPtr tagList, tmpTag;␊ |
228 | ␊ |
229 | tagList = 0;␊ |
230 | pos = 0;␊ |
231 | ␊ |
232 | if (!empty)␊ |
233 | {␊ |
234 | while (1)␊ |
235 | {␊ |
236 | length = XMLParseNextTag(buffer + pos, &tmpTag);␊ |
237 | if (length == -1) break;␊ |
238 | ␊ |
239 | pos += length;␊ |
240 | ␊ |
241 | if (tmpTag == 0) break;␊ |
242 | tmpTag->tagNext = tagList;␊ |
243 | tagList = tmpTag;␊ |
244 | }␊ |
245 | ␊ |
246 | if (length == -1)␊ |
247 | {␊ |
248 | XMLFreeTag(tagList);␊ |
249 | return -1;␊ |
250 | }␊ |
251 | }␊ |
252 | ␊ |
253 | tmpTag = NewTag();␊ |
254 | if (tmpTag == 0)␊ |
255 | {␊ |
256 | XMLFreeTag(tagList);␊ |
257 | return -1;␊ |
258 | }␊ |
259 | ␊ |
260 | tmpTag->type = type;␊ |
261 | tmpTag->string = 0;␊ |
262 | tmpTag->tag = tagList;␊ |
263 | tmpTag->tagNext = 0;␊ |
264 | ␊ |
265 | *tag = tmpTag;␊ |
266 | ␊ |
267 | return pos;␊ |
268 | }␊ |
269 | ␊ |
270 | //==========================================================================␊ |
271 | // ParseTagKey␊ |
272 | ␊ |
273 | static long␊ |
274 | ParseTagKey( char * buffer, TagPtr * tag )␊ |
275 | {␊ |
276 | long length, length2;␊ |
277 | char *string;␊ |
278 | TagPtr tmpTag, subTag;␊ |
279 | ␊ |
280 | length = FixDataMatchingTag(buffer, kXMLTagKey);␊ |
281 | if (length == -1) return -1;␊ |
282 | ␊ |
283 | length2 = XMLParseNextTag(buffer + length, &subTag);␊ |
284 | if (length2 == -1) return -1;␊ |
285 | ␊ |
286 | tmpTag = NewTag();␊ |
287 | if (tmpTag == 0)␊ |
288 | {␊ |
289 | XMLFreeTag(subTag);␊ |
290 | return -1;␊ |
291 | }␊ |
292 | ␊ |
293 | string = NewSymbol(buffer);␊ |
294 | if (string == 0)␊ |
295 | {␊ |
296 | XMLFreeTag(subTag);␊ |
297 | XMLFreeTag(tmpTag);␊ |
298 | return -1;␊ |
299 | }␊ |
300 | ␊ |
301 | tmpTag->type = kTagTypeKey;␊ |
302 | tmpTag->string = string;␊ |
303 | tmpTag->tag = subTag;␊ |
304 | tmpTag->tagNext = 0;␊ |
305 | ␊ |
306 | *tag = tmpTag;␊ |
307 | ␊ |
308 | return length + length2;␊ |
309 | }␊ |
310 | ␊ |
311 | //==========================================================================␊ |
312 | // ParseTagString␊ |
313 | ␊ |
314 | static long␊ |
315 | ParseTagString( char * buffer, TagPtr * tag )␊ |
316 | {␊ |
317 | long length;␊ |
318 | char * string;␊ |
319 | TagPtr tmpTag;␊ |
320 | ␊ |
321 | length = FixDataMatchingTag(buffer, kXMLTagString);␊ |
322 | if (length == -1) return -1;␊ |
323 | ␊ |
324 | tmpTag = NewTag();␊ |
325 | if (tmpTag == 0) return -1;␊ |
326 | ␊ |
327 | string = NewSymbol(buffer);␊ |
328 | if (string == 0)␊ |
329 | {␊ |
330 | XMLFreeTag(tmpTag);␊ |
331 | return -1;␊ |
332 | }␊ |
333 | ␊ |
334 | tmpTag->type = kTagTypeString;␊ |
335 | tmpTag->string = string;␊ |
336 | tmpTag->tag = 0;␊ |
337 | tmpTag->tagNext = 0;␊ |
338 | ␊ |
339 | *tag = tmpTag;␊ |
340 | return length;␊ |
341 | }␊ |
342 | ␊ |
343 | //==========================================================================␊ |
344 | // ParseTagInteger␊ |
345 | ␊ |
346 | static long␊ |
347 | ParseTagInteger( char * buffer, TagPtr * tag )␊ |
348 | {␊ |
349 | long length, integer;␊ |
350 | TagPtr tmpTag;␊ |
351 | ␊ |
352 | length = FixDataMatchingTag(buffer, kXMLTagInteger);␊ |
353 | if (length == -1) return -1;␊ |
354 | ␊ |
355 | tmpTag = NewTag();␊ |
356 | if (tmpTag == 0) return -1;␊ |
357 | ␊ |
358 | integer = 0;␊ |
359 | ␊ |
360 | tmpTag->type = kTagTypeInteger;␊ |
361 | tmpTag->string = (char *)integer;␊ |
362 | tmpTag->tag = 0;␊ |
363 | tmpTag->tagNext = 0;␊ |
364 | ␊ |
365 | *tag = tmpTag;␊ |
366 | ␊ |
367 | return length;␊ |
368 | }␊ |
369 | ␊ |
370 | //==========================================================================␊ |
371 | // ParseTagData␊ |
372 | ␊ |
373 | static long␊ |
374 | ParseTagData( char * buffer, TagPtr * tag )␊ |
375 | {␊ |
376 | long length;␊ |
377 | TagPtr tmpTag;␊ |
378 | ␊ |
379 | length = FixDataMatchingTag(buffer, kXMLTagData);␊ |
380 | if (length == -1) return -1;␊ |
381 | ␊ |
382 | tmpTag = NewTag();␊ |
383 | if (tmpTag == 0) return -1;␊ |
384 | ␊ |
385 | tmpTag->type = kTagTypeData;␊ |
386 | tmpTag->string = 0;␊ |
387 | tmpTag->tag = 0;␊ |
388 | tmpTag->tagNext = 0;␊ |
389 | ␊ |
390 | *tag = tmpTag;␊ |
391 | ␊ |
392 | return length;␊ |
393 | }␊ |
394 | ␊ |
395 | //==========================================================================␊ |
396 | // ParseTagDate␊ |
397 | ␊ |
398 | static long␊ |
399 | ParseTagDate( char * buffer, TagPtr * tag )␊ |
400 | {␊ |
401 | long length;␊ |
402 | TagPtr tmpTag;␊ |
403 | ␊ |
404 | length = FixDataMatchingTag(buffer, kXMLTagDate);␊ |
405 | if (length == -1) return -1;␊ |
406 | ␊ |
407 | tmpTag = NewTag();␊ |
408 | if (tmpTag == 0) return -1;␊ |
409 | ␊ |
410 | tmpTag->type = kTagTypeDate;␊ |
411 | tmpTag->string = 0;␊ |
412 | tmpTag->tag = 0;␊ |
413 | tmpTag->tagNext = 0;␊ |
414 | ␊ |
415 | *tag = tmpTag;␊ |
416 | ␊ |
417 | return length;␊ |
418 | }␊ |
419 | ␊ |
420 | //==========================================================================␊ |
421 | // ParseTagBoolean␊ |
422 | ␊ |
423 | static long␊ |
424 | ParseTagBoolean( char * buffer, TagPtr * tag, long type )␊ |
425 | {␊ |
426 | TagPtr tmpTag;␊ |
427 | ␊ |
428 | tmpTag = NewTag();␊ |
429 | if (tmpTag == 0) return -1;␊ |
430 | ␊ |
431 | tmpTag->type = type;␊ |
432 | tmpTag->string = 0;␊ |
433 | tmpTag->tag = 0;␊ |
434 | tmpTag->tagNext = 0;␊ |
435 | ␊ |
436 | *tag = tmpTag;␊ |
437 | ␊ |
438 | return 0;␊ |
439 | }␊ |
440 | ␊ |
441 | //==========================================================================␊ |
442 | // GetNextTag␊ |
443 | ␊ |
444 | static long␊ |
445 | GetNextTag( char * buffer, char ** tag, long * start )␊ |
446 | {␊ |
447 | long cnt, cnt2;␊ |
448 | ␊ |
449 | if (tag == 0) return -1;␊ |
450 | ␊ |
451 | // Find the start of the tag.␊ |
452 | cnt = 0;␊ |
453 | while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++;␊ |
454 | if (buffer[cnt] == '\0') return -1;␊ |
455 | ␊ |
456 | // Find the end of the tag.␊ |
457 | cnt2 = cnt + 1;␊ |
458 | while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++;␊ |
459 | if (buffer[cnt2] == '\0') return -1;␊ |
460 | ␊ |
461 | // Fix the tag data.␊ |
462 | *tag = buffer + cnt + 1;␊ |
463 | buffer[cnt2] = '\0';␊ |
464 | if (start) *start = cnt;␊ |
465 | ␊ |
466 | return cnt2 + 1;␊ |
467 | }␊ |
468 | ␊ |
469 | //==========================================================================␊ |
470 | // FixDataMatchingTag␊ |
471 | // Modifies 'buffer' to add a '\0' at the end of the tag matching 'tag'.␊ |
472 | // Returns the length of the data found, counting the end tag,␊ |
473 | // or -1 if the end tag was not found.␊ |
474 | ␊ |
475 | static long␊ |
476 | FixDataMatchingTag( char * buffer, char * tag )␊ |
477 | {␊ |
478 | long length, start, stop;␊ |
479 | char * endTag;␊ |
480 | ␊ |
481 | start = 0;␊ |
482 | while (1)␊ |
483 | {␊ |
484 | length = GetNextTag(buffer + start, &endTag, &stop);␊ |
485 | if (length == -1) return -1;␊ |
486 | ␊ |
487 | if ((*endTag == '/') && !strcmp(endTag + 1, tag)) break;␊ |
488 | start += length;␊ |
489 | }␊ |
490 | ␊ |
491 | buffer[start + stop] = '\0';␊ |
492 | ␊ |
493 | return start + length;␊ |
494 | }␊ |
495 | ␊ |
496 | //==========================================================================␊ |
497 | // NewTag␊ |
498 | ␊ |
499 | #define kTagsPerBlock (0x1000)␊ |
500 | ␊ |
501 | static TagPtr gTagsFree;␊ |
502 | ␊ |
503 | static TagPtr␊ |
504 | NewTag( void )␊ |
505 | {␊ |
506 | ␉long cnt;␊ |
507 | ␉TagPtr tag;␊ |
508 | ␊ |
509 | if (gTagsFree == 0)␊ |
510 | {␊ |
511 | #if USEMALLOC␊ |
512 | tag = (TagPtr)malloc(kTagsPerBlock * sizeof(Tag));␊ |
513 | #else␊ |
514 | tag = (TagPtr)AllocateBootXMemory(kTagsPerBlock * sizeof(Tag));␊ |
515 | #endif␊ |
516 | if (tag == 0) return 0;␊ |
517 | ␊ |
518 | // Initalize the new tags.␊ |
519 | for (cnt = 0; cnt < kTagsPerBlock; cnt++)␊ |
520 | {␊ |
521 | tag[cnt].type = kTagTypeNone;␊ |
522 | tag[cnt].string = 0;␊ |
523 | tag[cnt].tag = 0;␊ |
524 | tag[cnt].tagNext = tag + cnt + 1;␊ |
525 | }␊ |
526 | tag[kTagsPerBlock - 1].tagNext = 0;␊ |
527 | ␊ |
528 | gTagsFree = tag;␊ |
529 | }␊ |
530 | ␊ |
531 | tag = gTagsFree;␊ |
532 | gTagsFree = tag->tagNext;␊ |
533 | ␊ |
534 | return tag;␊ |
535 | }␊ |
536 | ␊ |
537 | //==========================================================================␊ |
538 | // XMLFreeTag␊ |
539 | ␊ |
540 | void␊ |
541 | XMLFreeTag( TagPtr tag )␊ |
542 | {␊ |
543 | #if DOFREE␊ |
544 | if (tag == 0) return;␊ |
545 | ␊ |
546 | if (tag->string) FreeSymbol(tag->string);␊ |
547 | ␊ |
548 | XMLFreeTag(tag->tag);␊ |
549 | XMLFreeTag(tag->tagNext);␊ |
550 | ␊ |
551 | // Clear and free the tag.␊ |
552 | tag->type = kTagTypeNone;␊ |
553 | tag->string = 0;␊ |
554 | tag->tag = 0;␊ |
555 | tag->tagNext = gTagsFree;␊ |
556 | gTagsFree = tag;␊ |
557 | #else␊ |
558 | return;␊ |
559 | #endif␊ |
560 | }␊ |
561 | ␊ |
562 | //==========================================================================␊ |
563 | // Symbol object.␊ |
564 | ␊ |
565 | struct Symbol␊ |
566 | {␊ |
567 | long refCount;␊ |
568 | struct Symbol *next;␊ |
569 | char string[];␊ |
570 | };␊ |
571 | typedef struct Symbol Symbol, *SymbolPtr;␊ |
572 | ␊ |
573 | static SymbolPtr FindSymbol(char * string, SymbolPtr * prevSymbol);␊ |
574 | ␊ |
575 | static SymbolPtr gSymbolsHead;␊ |
576 | ␊ |
577 | //==========================================================================␊ |
578 | // NewSymbol␊ |
579 | ␊ |
580 | static char *␊ |
581 | NewSymbol( char * string )␊ |
582 | {␊ |
583 | static SymbolPtr lastGuy = 0;␊ |
584 | ␉SymbolPtr symbol;␊ |
585 | ␊ |
586 | // Look for string in the list of symbols.␊ |
587 | symbol = FindSymbol(string, 0);␊ |
588 | ␊ |
589 | // Add the new symbol.␊ |
590 | if (symbol == 0)␊ |
591 | {␊ |
592 | #if USEMALLOC␊ |
593 | symbol = (SymbolPtr)malloc(sizeof(Symbol) + 1 + strlen(string));␊ |
594 | #else␊ |
595 | symbol = (SymbolPtr)AllocateBootXMemory(sizeof(Symbol) + 1 + strlen(string));␊ |
596 | #endif␊ |
597 | if (symbol == 0) //return 0;␊ |
598 | stop("NULL symbol!");␊ |
599 | ␊ |
600 | // Set the symbol's data.␊ |
601 | symbol->refCount = 0;␊ |
602 | strcpy(symbol->string, string);␊ |
603 | ␊ |
604 | // Add the symbol to the list.␊ |
605 | symbol->next = gSymbolsHead;␊ |
606 | gSymbolsHead = symbol;␊ |
607 | }␊ |
608 | ␊ |
609 | // Update the refCount and return the string.␊ |
610 | symbol->refCount++;␊ |
611 | ␊ |
612 | if (lastGuy && lastGuy->next != 0) stop("last guy not last!");␊ |
613 | return symbol->string;␊ |
614 | }␊ |
615 | ␊ |
616 | //==========================================================================␊ |
617 | // FreeSymbol␊ |
618 | ␊ |
619 | #if DOFREE␊ |
620 | static void␊ |
621 | FreeSymbol( char * string )␊ |
622 | { ␊ |
623 | SymbolPtr symbol, prev;␊ |
624 | ␉prev = 0;␊ |
625 | ␊ |
626 | // Look for string in the list of symbols.␊ |
627 | symbol = FindSymbol(string, &prev);␊ |
628 | if (symbol == 0) return;␊ |
629 | ␊ |
630 | // Update the refCount.␊ |
631 | symbol->refCount--;␊ |
632 | ␊ |
633 | if (symbol->refCount != 0) return;␊ |
634 | ␊ |
635 | // Remove the symbol from the list.␊ |
636 | if (prev != 0) prev->next = symbol->next;␊ |
637 | else gSymbolsHead = symbol->next;␊ |
638 | ␊ |
639 | // Free the symbol's memory.␊ |
640 | free(symbol);␊ |
641 | }␊ |
642 | #endif␊ |
643 | ␊ |
644 | //==========================================================================␊ |
645 | // FindSymbol␊ |
646 | ␊ |
647 | static SymbolPtr␊ |
648 | FindSymbol( char * string, SymbolPtr * prevSymbol )␊ |
649 | {␊ |
650 | SymbolPtr symbol, prev;␊ |
651 | ␊ |
652 | symbol = gSymbolsHead;␊ |
653 | prev = 0;␊ |
654 | ␊ |
655 | while (symbol != 0) {␊ |
656 | if (!strcmp(symbol->string, string)) break;␊ |
657 | ␊ |
658 | prev = symbol;␊ |
659 | symbol = symbol->next;␊ |
660 | }␊ |
661 | ␊ |
662 | if ((symbol != 0) && (prevSymbol != 0)) *prevSymbol = prev;␊ |
663 | ␊ |
664 | return symbol;␊ |
665 | }␊ |
666 |