1 /* asmpars.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Verwaltung von Symbolen und das ganze Drumherum... */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 #include <assert.h>
15
16 #include "endian.h"
17 #include "bpemu.h"
18 #include "nls.h"
19 #include "nlmessages.h"
20 #include "as.rsc"
21 #include "strutil.h"
22 #include "strcomp.h"
23
24 #include "asmdef.h"
25 #include "asmsub.h"
26 #include "errmsg.h"
27 #include "asmfnums.h"
28 #include "asmrelocs.h"
29 #include "asmstructs.h"
30 #include "chunks.h"
31 #include "trees.h"
32 #include "operator.h"
33 #include "function.h"
34 #include "ieeefloat.h"
35
36 #include "asmpars.h"
37
38 #define LOCSYMSIGHT 3 /* max. sight for nameless temporary symbols */
39
40 /* Mask, Min 6 Max are computed at initialization */
41
42 tIntTypeDef IntTypeDefs[IntTypeCnt] =
43 {
44 { 0x0001, 0, 0, 0 }, /* UInt1 */
45 { 0x0002, 0, 0, 0 }, /* UInt2 */
46 { 0x0003, 0, 0, 0 }, /* UInt3 */
47 { 0x8004, 0, 0, 0 }, /* SInt4 */
48 { 0x0004, 0, 0, 0 }, /* UInt4 */
49 { 0xc004, 0, 0, 0 }, /* Int4 */
50 { 0x8005, 0, 0, 0 }, /* SInt5 */
51 { 0x0005, 0, 0, 0 }, /* UInt5 */
52 { 0xc005, 0, 0, 0 }, /* Int5 */
53 { 0x8006, 0, 0, 0 }, /* SInt6 */
54 { 0x0006, 0, 0, 0 }, /* UInt6 */
55 { 0x8007, 0, 0, 0 }, /* SInt7 */
56 { 0x0007, 0, 0, 0 }, /* UInt7 */
57 { 0x8008, 0, 0, 0 }, /* SInt8 */
58 { 0x0008, 0, 0, 0 }, /* UInt8 */
59 { 0xc008, 0, 0, 0 }, /* Int8 */
60 { 0x8009, 0, 0, 0 }, /* SInt9 */
61 { 0x0009, 0, 0, 0 }, /* UInt9 */
62 { 0x000a, 0, 0, 0 }, /* UInt10 */
63 { 0xc00a, 0, 0, 0 }, /* Int10 */
64 { 0x000b, 0, 0, 0 }, /* UInt11 */
65 { 0x000c, 0, 0, 0 }, /* UInt12 */
66 { 0xc00c, 0, 0, 0 }, /* Int12 */
67 { 0x000d, 0, 0, 0 }, /* UInt13 */
68 { 0x000e, 0, 0, 0 }, /* UInt14 */
69 { 0xc00e, 0, 0, 0 }, /* Int14 */
70 { 0x800f, 0, 0, 0 }, /* SInt15 */
71 { 0x000f, 0, 0, 0 }, /* UInt15 */
72 { 0x8010, 0, 0, 0 }, /* SInt16 */
73 { 0x0010, 0, 0, 0 }, /* UInt16 */
74 { 0xc010, 0, 0, 0 }, /* Int16 */
75 { 0x0011, 0, 0, 0 }, /* UInt17 */
76 { 0x0012, 0, 0, 0 }, /* UInt18 */
77 { 0x0013, 0, 0, 0 }, /* UInt19 */
78 { 0x8014, 0, 0, 0 }, /* SInt20 */
79 { 0x0014, 0, 0, 0 }, /* UInt20 */
80 { 0xc014, 0, 0, 0 }, /* Int20 */
81 { 0x0015, 0, 0, 0 }, /* UInt21 */
82 { 0x0016, 0, 0, 0 }, /* UInt22 */
83 { 0x0017, 0, 0, 0 }, /* UInt23 */
84 { 0x8018, 0, 0, 0 }, /* SInt24 */
85 { 0x0018, 0, 0, 0 }, /* UInt24 */
86 { 0xc018, 0, 0, 0 }, /* Int24 */
87 { 0x8020, 0, 0, 0 }, /* SInt32 */
88 { 0x0020, 0, 0, 0 }, /* UInt32 */
89 { 0xc020, 0, 0, 0 }, /* Int32 */
90 #ifdef HAS64
91 { 0x8040, 0, 0, 0 }, /* SInt64 */
92 { 0x0040, 0, 0, 0 }, /* UInt64 */
93 { 0xc040, 0, 0, 0 }, /* Int64 */
94 #endif
95 };
96
97 typedef struct
98 {
99 Boolean Back;
100 LongInt Counter;
101 } TTmpSymLog;
102
103 LongInt MomLocHandle; /* Merker, den lokale Symbole erhalten */
104 LongInt TmpSymCounter, /* counters for local symbols */
105 FwdSymCounter,
106 BackSymCounter;
107 char TmpSymCounterVal[10]; /* representation as string */
108 TTmpSymLog TmpSymLog[LOCSYMSIGHT];
109 LongInt TmpSymLogDepth;
110
111 LongInt LocHandleCnt; /* mom. verwendeter lokaler Handle */
112
113 static char BaseIds[3] =
114 {
115 '%', '@', '$'
116 };
117 static char BaseLetters[4] =
118 {
119 'B', 'O', 'H', 'Q'
120 };
121 static Byte BaseVals[4] =
122 {
123 2, 8, 16, 8
124 };
125
126 typedef struct sSymbolEntry
127 {
128 TTree Tree;
129 Byte SymType;
130 tSymbolSize SymSize;
131 Boolean Defined, Used, Changeable;
132 SymbolVal SymWert;
133 PCrossRef RefList;
134 Byte FileNum;
135 LongInt LineNum;
136 tSymbolFlags Flags;
137 TRelocEntry *Relocs;
138 } TSymbolEntry, *PSymbolEntry;
139
140 typedef struct sSymbolStackEntry
141 {
142 struct sSymbolStackEntry *Next;
143 SymbolVal Contents;
144 } TSymbolStackEntry, *PSymbolStackEntry;
145
146 typedef struct sSymbolStack
147 {
148 struct sSymbolStack *Next;
149 char *Name;
150 PSymbolStackEntry Contents;
151 } TSymbolStack, *PSymbolStack;
152
153 typedef struct sDefSymbol
154 {
155 struct sDefSymbol *Next;
156 char *SymName;
157 TempResult Wert;
158 } TDefSymbol, *PDefSymbol;
159
160 typedef struct sCToken
161 {
162 struct sCToken *Next;
163 char *Name;
164 LongInt Parent;
165 ChunkList Usage;
166 } TCToken, *PCToken;
167
168 typedef struct sLocHeap
169 {
170 struct sLocHeap *Next;
171 LongInt Cont;
172 } TLocHeap, *PLocHandle;
173
174 typedef struct sRegDefList
175 {
176 struct sRegDefList *Next;
177 LongInt Section;
178 char *Value;
179 Boolean Used;
180 } TRegDefList, *PRegDefList;
181
182 typedef struct sRegDef
183 {
184 struct sRegDef *Left, *Right;
185 char *Orig;
186 PRegDefList Defs, DoneDefs;
187 } TRegDef, *PRegDef;
188
189 static PSymbolEntry FirstSymbol, FirstLocSymbol;
190 static PDefSymbol FirstDefSymbol;
191 /*static*/ PCToken FirstSection;
192 static Boolean DoRefs, /* Querverweise protokollieren */
193 RegistersDefined;
194 static PLocHandle FirstLocHandle;
195 static PSymbolStack FirstStack;
196 static PCToken MomSection;
197 static char *LastGlobSymbol;
198 static PFunction FirstFunction; /* Liste definierter Funktionen */
199
AsmParsInit(void)200 void AsmParsInit(void)
201 {
202 FirstSymbol = NULL;
203
204 FirstLocSymbol = NULL; MomLocHandle = -1; SetMomSection(-1);
205 FirstSection = NULL;
206 FirstLocHandle = NULL;
207 FirstStack = NULL;
208 FirstFunction = NULL;
209 DoRefs = True;
210 RadixBase = 10;
211 OutRadixBase = 16;
212 RegistersDefined = False;
213 }
214
215
RangeCheck(LargeInt Wert,IntType Typ)216 Boolean RangeCheck(LargeInt Wert, IntType Typ)
217 {
218 #ifndef HAS64
219 if (((int)Typ) >= ((int)SInt32))
220 return True;
221 #else
222 if (((int)Typ) >= ((int)Int64))
223 return True;
224 #endif
225 else
226 return ((Wert >= IntTypeDefs[(int)Typ].Min) && (Wert <= IntTypeDefs[(int)Typ].Max));
227 }
228
FloatRangeCheck(Double Wert,FloatType Typ)229 Boolean FloatRangeCheck(Double Wert, FloatType Typ)
230 {
231 /* NaN/Infinity is representable in all formats */
232
233 int numclass = as_fpclassify(Wert);
234 if ((numclass == AS_FP_NAN) || (numclass == AS_FP_INFINITE))
235 return True;
236
237 switch (Typ)
238 {
239 case Float16:
240 return (fabs(Wert) <= 65504.0);
241 case Float32:
242 return (fabs(Wert) <= 3.4e38);
243 case Float64:
244 return (fabs(Wert) <= 1.7e308);
245 /** case FloatCo: return fabs(Wert) <= 9.22e18; */
246 case Float80:
247 return True;
248 case FloatDec:
249 return True;
250 default:
251 return False;
252 }
253 /** if (Typ == FloatDec) && (fabs(Wert) > 1e1000) WrError(ErrNum_BigDecFloat);**/
254 }
255
SingleBit(LargeInt Inp,LargeInt * Erg)256 Boolean SingleBit(LargeInt Inp, LargeInt *Erg)
257 {
258 *Erg = 0;
259 do
260 {
261 if (!Odd(Inp))
262 (*Erg)++;
263 if (!Odd(Inp))
264 Inp = Inp >> 1;
265 }
266 while ((*Erg != LARGEBITS) && (!Odd(Inp)));
267 return (*Erg != LARGEBITS) && (Inp == 1);
268 }
269
GetSmallestUIntType(LargeWord MaxValue)270 IntType GetSmallestUIntType(LargeWord MaxValue)
271 {
272 IntType Result;
273
274 Result = (IntType) 0;
275 for (Result = (IntType) 0; Result < IntTypeCnt; Result++)
276 {
277 if (IntTypeDefs[Result].Min < 0)
278 continue;
279 if (IntTypeDefs[Result].Max >= (LargeInt)MaxValue)
280 return Result;
281 }
282 return UInt32;
283 }
284
ProcessBk(char ** Start,char * Erg)285 static Boolean ProcessBk(char **Start, char *Erg)
286 {
287 LongInt System = 0, Acc = 0, Digit = 0;
288 char ch;
289 int cnt;
290 Boolean Finish;
291
292 switch (as_toupper(**Start))
293 {
294 case '\'': case '\\': case '"':
295 *Erg = **Start;
296 (*Start)++;
297 return True;
298 case 'H':
299 *Erg = '\'';
300 (*Start)++;
301 return True;
302 case 'I':
303 *Erg = '"';
304 (*Start)++;
305 return True;
306 case 'B':
307 *Erg = Char_BS;
308 (*Start)++;
309 return True;
310 case 'A':
311 *Erg = Char_BEL;
312 (*Start)++;
313 return True;
314 case 'E':
315 *Erg = Char_ESC;
316 (*Start)++;
317 return True;
318 case 'T':
319 *Erg = Char_HT;
320 (*Start)++;
321 return True;
322 case 'N':
323 *Erg = Char_LF;
324 (*Start)++;
325 return True;
326 case 'R':
327 *Erg = Char_CR;
328 (*Start)++;
329 return True;
330 case 'X':
331 System = 16;
332 (*Start)++;
333 /* fall-through */
334 case '0': case '1': case '2': case '3': case '4':
335 case '5': case '6': case '7': case '8': case '9':
336 if (System == 0)
337 System = (**Start == '0') ? 8 : 10;
338 cnt = (System == 16) ? 1 : ((System == 10) ? 0 : -1);
339 do
340 {
341 ch = as_toupper(**Start);
342 Finish = False;
343 if ((ch >= '0') && (ch <= '9'))
344 Digit = ch - '0';
345 else if ((System == 16) && (ch >= 'A') && (ch <= 'F'))
346 Digit = (ch - 'A') + 10;
347 else
348 Finish = True;
349 if (!Finish)
350 {
351 (*Start)++;
352 cnt++;
353 if (Digit >= System)
354 {
355 WrError(ErrNum_OverRange);
356 return False;
357 }
358 Acc = (Acc * System) + Digit;
359 }
360 }
361 while ((!Finish) && (cnt < 3));
362 if (!ChkRange(Acc, 0, 255))
363 return False;
364 *Erg = Acc;
365 return True;
366 default:
367 WrError(ErrNum_InvEscSequence);
368 return False;
369 }
370 }
371
372 /*!------------------------------------------------------------------------
373 * \fn DynString2Int(const struct sDynString *pDynString)
374 * \brief convert string to its "ASCII representation"
375 * \param pDynString string containing characters
376 * \return -1 or converted int
377 * ------------------------------------------------------------------------ */
378
DynString2Int(const struct sDynString * pDynString)379 LargeInt DynString2Int(const struct sDynString *pDynString)
380 {
381 if ((pDynString->Length > 0) && (pDynString->Length <= 4))
382 {
383 const char *pRun;
384 Byte Digit;
385 LargeInt Result;
386
387 Result = 0;
388 for (pRun = pDynString->Contents;
389 pRun < pDynString->Contents + pDynString->Length;
390 pRun++)
391 {
392 Digit = (usint) *pRun;
393 Result = (Result << 8) | CharTransTable[Digit & 0xff];
394 }
395 return Result;
396 }
397 return -1;
398 }
399
Int2DynString(struct sDynString * pDynString,LargeInt Src)400 Boolean Int2DynString(struct sDynString *pDynString, LargeInt Src)
401 {
402 int Search;
403 Byte Digit;
404 char *pDest = &pDynString->Contents[sizeof(pDynString->Contents)];
405
406 pDynString->Length = 0;
407 while (Src)
408 {
409 Digit = Src & 0xff;
410 Src = (Src >> 8) & 0xfffffful;
411 for (Search = 0; Search < 256; Search++)
412 if (CharTransTable[Search] == Digit)
413 {
414 *(--pDest) = Search;
415 pDynString->Length++;
416 break;
417 }
418 }
419 memmove(pDynString->Contents, pDest, pDynString->Length);
420 return True;
421 }
422
423 /*!------------------------------------------------------------------------
424 * \fn TempResultToInt(TempResult *pResult)
425 * \brief convert TempResult to integer
426 * \param pResult tempresult to convert
427 * \return 0 or error code
428 * ------------------------------------------------------------------------ */
429
TempResultToInt(TempResult * pResult)430 int TempResultToInt(TempResult *pResult)
431 {
432 switch (pResult->Typ)
433 {
434 case TempInt:
435 break;
436 case TempString:
437 {
438 LargeInt Result = DynString2Int(&pResult->Contents.Ascii);
439 if (Result >= 0)
440 {
441 pResult->Typ = TempInt;
442 pResult->Contents.Int = Result;
443 break;
444 }
445 /* else */
446 }
447 /* fall-through */
448 default:
449 pResult->Typ = TempNone;
450 return -1;
451 }
452 return 0;
453 }
454
455 /*!------------------------------------------------------------------------
456 * \fn MultiCharToInt(TempResult *pResult, unsigned MaxLen)
457 * \brief optionally convert multi-character constant to integer
458 * \param pResult holding value
459 * \param MaxLen maximum lenght of multi-character constant
460 * \return True if converted
461 * ------------------------------------------------------------------------ */
462
MultiCharToInt(TempResult * pResult,unsigned MaxLen)463 Boolean MultiCharToInt(TempResult *pResult, unsigned MaxLen)
464 {
465 if ((pResult->Contents.Ascii.Length <= MaxLen) && (pResult->Flags & eSymbolFlag_StringSingleQuoted))
466 {
467 TempResultToInt(pResult);
468 return True;
469 }
470 return False;
471 }
472
473 /*!------------------------------------------------------------------------
474 * \fn ExpandStrSymbol(char *pDest, size_t DestSize, const tStrComp *pSrc)
475 * \brief expand symbol name from string component
476 * \param pDest dest buffer
477 * \param DestSize size of dest buffer
478 * \param pSrc source component
479 * \return True if success
480 * ------------------------------------------------------------------------ */
481
ExpandStrSymbol(char * pDest,size_t DestSize,const tStrComp * pSrc)482 Boolean ExpandStrSymbol(char *pDest, size_t DestSize, const tStrComp *pSrc)
483 {
484 tStrComp SrcComp;
485 const char *pStart;
486
487 *pDest = '\0'; StrCompRefRight(&SrcComp, pSrc, 0);
488 while (True)
489 {
490 pStart = strchr(SrcComp.Str, '{');
491 if (pStart)
492 {
493 unsigned ls = pStart - SrcComp.Str, ld = strlen(pDest);
494 String Expr, Result;
495 tStrComp ExprComp;
496 tEvalResult EvalResult;
497 const char *pStop;
498
499 if (ld + ls + 1 > DestSize)
500 ls = DestSize - 1 - ld;
501 memcpy(pDest + ld, SrcComp.Str, ls);
502 pDest[ld + ls] = '\0';
503
504 pStop = QuotPos(pStart + 1, '}');
505 if (!pStop)
506 {
507 WrStrErrorPos(ErrNum_InvSymName, pSrc);
508 return False;
509 }
510 StrCompMkTemp(&ExprComp, Expr);
511 StrCompCopySub(&ExprComp, &SrcComp, pStart + 1 - SrcComp.Str, pStop - pStart - 1);
512 EvalStrStringExpressionWithResult(&ExprComp, &EvalResult, Result);
513 if (!EvalResult.OK)
514 return False;
515 if (mFirstPassUnknown(EvalResult.Flags))
516 {
517 WrStrErrorPos(ErrNum_FirstPassCalc, &ExprComp);
518 return False;
519 }
520 if (!CaseSensitive)
521 UpString(Result);
522 strmaxcat(pDest, Result, DestSize);
523 StrCompIncRefLeft(&SrcComp, pStop + 1 - SrcComp.Str);
524 }
525 else
526 {
527 strmaxcat(pDest, SrcComp.Str, DestSize);
528 return True;
529 }
530 }
531 }
532
533 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
534 /* check whether this is a local symbol and expand local counter if yes. They
535 have to be handled in different places of the parser, therefore two separate
536 functions */
537
InitTmpSymbols(void)538 void InitTmpSymbols(void)
539 {
540 TmpSymCounter = FwdSymCounter = BackSymCounter = 0;
541 *TmpSymCounterVal = '\0';
542 TmpSymLogDepth = 0;
543 *LastGlobSymbol = '\0';
544 }
545
AddTmpSymLog(Boolean Back,LongInt Counter)546 static void AddTmpSymLog(Boolean Back, LongInt Counter)
547 {
548 /* shift out oldest value */
549
550 if (TmpSymLogDepth)
551 {
552 LongInt ShiftCnt = min(TmpSymLogDepth, LOCSYMSIGHT - 1);
553
554 memmove(TmpSymLog + 1, TmpSymLog, sizeof(TTmpSymLog) * (ShiftCnt));
555 }
556
557 /* insert new one */
558
559 TmpSymLog[0].Back = Back;
560 TmpSymLog[0].Counter = Counter;
561 if (TmpSymLogDepth < LOCSYMSIGHT)
562 TmpSymLogDepth++;
563 }
564
ChkTmp1(char * Name,Boolean Define)565 static Boolean ChkTmp1(char *Name, Boolean Define)
566 {
567 char *Src, *Dest;
568 Boolean Result = FALSE;
569
570 /* $$-Symbols: append current $$-counter */
571
572 if (!strncmp(Name, "$$", 2))
573 {
574 /* manually copy since this will implicitly give us the point to append
575 the number */
576
577 for (Src = Name + 2, Dest = Name; *Src; *(Dest++) = *(Src++));
578
579 /* append number. only generate the number once */
580
581 if (*TmpSymCounterVal == '\0')
582 as_snprintf(TmpSymCounterVal, sizeof(TmpSymCounterVal), "%d", TmpSymCounter);
583 strcpy(Dest, TmpSymCounterVal);
584 Result = TRUE;
585 }
586
587 /* no special local symbol: increment $$-counter */
588
589 else if (Define)
590 {
591 TmpSymCounter++;
592 *TmpSymCounterVal = '\0';
593 }
594
595 return Result;
596 }
597
ChkTmp2(char * pDest,const char * pSrc,Boolean Define)598 static Boolean ChkTmp2(char *pDest, const char *pSrc, Boolean Define)
599 {
600 const char *pRun, *pBegin, *pEnd;
601 int Cnt;
602 Boolean Result = FALSE;
603
604 for (pBegin = pSrc; as_isspace(*pBegin); pBegin++);
605 for (pEnd = pSrc + strlen(pSrc); (pEnd > pBegin) && as_isspace(*(pEnd - 1)); pEnd--);
606
607 /* Note: We have to deal with three symbol definitions:
608
609 "-" for backward-only referencing
610 "+" for forward-only referencing
611 "/" for either way of referencing
612
613 "/" and "+" are both expanded to forward symbol names, so the
614 forward refencing to both types is unproblematic, however
615 only "/" and "-" are stored in the backlog of the three
616 most-recent symbols for backward referencing.
617 */
618
619 /* backward references ? */
620
621 if (*pBegin == '-')
622 {
623 for (pRun = pBegin; *pRun; pRun++)
624 if (*pRun != '-')
625 break;
626 Cnt = pRun - pBegin;
627 if (pRun == pEnd)
628 {
629 if ((Define) && (Cnt == 1))
630 {
631 as_snprintf(pDest, STRINGSIZE, "__back%d", (int)BackSymCounter);
632 AddTmpSymLog(TRUE, BackSymCounter);
633 BackSymCounter++;
634 Result = TRUE;
635 }
636
637 /* TmpSymLogDepth cannot become larger than LOCSYMSIGHT, so we only
638 have to check against the log's actual depth. */
639
640 else if (Cnt <= TmpSymLogDepth)
641 {
642 Cnt--;
643 as_snprintf(pDest, STRINGSIZE, "__%s%d",
644 TmpSymLog[Cnt].Back ? "back" : "forw",
645 (int)TmpSymLog[Cnt].Counter);
646 Result = TRUE;
647 }
648 }
649 }
650
651 /* forward references ? */
652
653 else if (*pBegin == '+')
654 {
655 for (pRun = pBegin; *pRun; pRun++)
656 if (*pRun != '+')
657 break;
658 Cnt = pRun - pBegin;
659 if (pRun == pEnd)
660 {
661 if ((Define) && (Cnt == 1))
662 {
663 as_snprintf(pDest, STRINGSIZE, "__forw%d", (int)FwdSymCounter++);
664 Result = TRUE;
665 }
666 else if (Cnt <= LOCSYMSIGHT)
667 {
668 as_snprintf(pDest, STRINGSIZE, "__forw%d", (int)(FwdSymCounter + (Cnt - 1)));
669 Result = TRUE;
670 }
671 }
672 }
673
674 /* slash: only allowed for definition, but add to log for backward ref. */
675
676 else if ((pEnd - pBegin == 1) && (*pBegin == '/') && Define)
677 {
678 AddTmpSymLog(FALSE, FwdSymCounter);
679 as_snprintf(pDest, STRINGSIZE, "__forw%d", (int)FwdSymCounter);
680 FwdSymCounter++;
681 Result = TRUE;
682 }
683
684 return Result;
685 }
686
ChkTmp3(char * Name,Boolean Define)687 static Boolean ChkTmp3(char *Name, Boolean Define)
688 {
689 Boolean Result = FALSE;
690
691 if ('.' == *Name)
692 {
693 String Tmp;
694
695 strmaxcpy(Tmp, LastGlobSymbol, STRINGSIZE);
696 strmaxcat(Tmp, Name, STRINGSIZE);
697 strmaxcpy(Name, Tmp, STRINGSIZE);
698
699 Result = TRUE;
700 }
701 else if (Define)
702 {
703 strmaxcpy(LastGlobSymbol, Name, STRINGSIZE);
704 }
705
706 return Result;
707 }
708
ChkTmp(char * Name,Boolean Define)709 static Boolean ChkTmp(char *Name, Boolean Define)
710 {
711 Boolean IsTmp1, IsTmp2, IsTmp3;
712
713 IsTmp1 = ChkTmp1(Name, Define);
714 IsTmp2 = ChkTmp2(Name, Name, Define);
715 IsTmp3 = ChkTmp3(Name, Define && !IsTmp2);
716 return IsTmp1 || IsTmp2 || IsTmp3;
717 }
718
IdentifySection(const tStrComp * pName,LongInt * Erg)719 Boolean IdentifySection(const tStrComp *pName, LongInt *Erg)
720 {
721 PSaveSection SLauf;
722 String ExpName;
723 sint Depth;
724
725 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
726 return False;
727 if (!CaseSensitive)
728 NLS_UpString(ExpName);
729
730 if (*ExpName == '\0')
731 {
732 *Erg = -1;
733 return True;
734 }
735 else if (((strlen(ExpName) == 6) || (strlen(ExpName) == 7))
736 && (!as_strncasecmp(ExpName, "PARENT", 6))
737 && ((strlen(ExpName) == 6) || ((ExpName[6] >= '0') && (ExpName[6] <= '9'))))
738 {
739 Depth = (strlen(ExpName) == 6) ? 1 : ExpName[6] - AscOfs;
740 SLauf = SectionStack;
741 *Erg = MomSectionHandle;
742 while ((Depth > 0) && (*Erg != -2))
743 {
744 if (!SLauf) *Erg = -2;
745 else
746 {
747 *Erg = SLauf->Handle;
748 SLauf = SLauf->Next;
749 }
750 Depth--;
751 }
752 if (*Erg == -2)
753 {
754 WrError(ErrNum_InvSection);
755 return False;
756 }
757 else
758 return True;
759 }
760 else if (!strcmp(ExpName, GetSectionName(MomSectionHandle)))
761 {
762 *Erg = MomSectionHandle;
763 return True;
764 }
765 else
766 {
767 SLauf = SectionStack;
768 while ((SLauf) && (strcmp(GetSectionName(SLauf->Handle), ExpName)))
769 SLauf = SLauf->Next;
770 if (!SLauf)
771 {
772 WrError(ErrNum_InvSection);
773 return False;
774 }
775 else
776 {
777 *Erg = SLauf->Handle;
778 return True;
779 }
780 }
781 }
782
GetSymSection(char * Name,LongInt * Erg,const tStrComp * pUnexpComp)783 static Boolean GetSymSection(char *Name, LongInt *Erg, const tStrComp *pUnexpComp)
784 {
785 String Part;
786 tStrComp TmpComp;
787 char *q;
788 int l = strlen(Name);
789
790 if (Name[l - 1] != ']')
791 {
792 *Erg = -2;
793 return True;
794 }
795
796 Name[l - 1] = '\0';
797 q = RQuotPos(Name, '[');
798 Name[l - 1] = ']';
799 if (Name + l - q <= 1)
800 {
801 if (pUnexpComp)
802 WrStrErrorPos(ErrNum_InvSymName, pUnexpComp);
803 else
804 WrXError(ErrNum_InvSymName, Name);
805 return False;
806 }
807
808 Name[l - 1] = '\0';
809 strmaxcpy(Part, q + 1, STRINGSIZE);
810 *q = '\0';
811
812 StrCompMkTemp(&TmpComp, Part);
813 return IdentifySection(&TmpComp, Erg);
814 }
815
816 /*****************************************************************************
817 * Function: ConstIntVal
818 * Purpose: evaluate integer constant
819 * Result: integer value
820 *****************************************************************************/
821
ConstIntVal(const char * pExpr,IntType Typ,Boolean * pResult)822 static LargeInt ConstIntVal(const char *pExpr, IntType Typ, Boolean *pResult)
823 {
824 LargeInt Wert;
825 int l;
826 Boolean NegFlag = False;
827 TConstMode ActMode = ConstModeC;
828 unsigned BaseIdx;
829 int Digit;
830 int Base;
831 char ch;
832 Boolean Found;
833
834
835 /* empty string is interpreted as 0 */
836
837 if (!*pExpr)
838 {
839 *pResult = True;
840 return 0;
841 }
842
843 *pResult = False;
844 Wert = 0;
845
846 /* sign: */
847
848 switch (*pExpr)
849 {
850 case '-':
851 NegFlag = True;
852 /* else fall-through */
853 case '+':
854 pExpr++;
855 break;
856 }
857 l = strlen(pExpr);
858
859 /* automatic syntax determination: */
860
861 if (RelaxedMode)
862 {
863 Found = False;
864
865 if ((l >= 2) && (*pExpr == '0') && (as_toupper(pExpr[1]) == 'X'))
866 {
867 ActMode = ConstModeC;
868 Found = True;
869 }
870
871 if ((!Found) && (l >= 2))
872 {
873 for (BaseIdx = 0; BaseIdx < 3; BaseIdx++)
874 if (*pExpr == BaseIds[BaseIdx])
875 {
876 ActMode = ConstModeMoto;
877 Found = True;
878 break;
879 }
880 }
881
882 if ((!Found) && (l >= 2) && (*pExpr >= '0') && (*pExpr <= '9'))
883 {
884 ch = as_toupper(pExpr[l - 1]);
885 if (DigitVal(ch, RadixBase) == -1)
886 {
887 for (BaseIdx = 0; BaseIdx < sizeof(BaseLetters) / sizeof(*BaseLetters); BaseIdx++)
888 if (ch == BaseLetters[BaseIdx])
889 {
890 ActMode = ConstModeIntel;
891 Found = True;
892 break;
893 }
894 }
895 }
896
897 if (!Found
898 && (l >= 3)
899 && (pExpr[1] == '\'')
900 && ((pExpr[l - 1] == '\'') || ConstModeWeirdNoTerm))
901 {
902 switch (as_toupper(*pExpr))
903 {
904 case 'H':
905 case 'X':
906 case 'B':
907 case 'O':
908 ActMode = ConstModeWeird;
909 Found = True;
910 break;
911 }
912 }
913
914 if (!Found)
915 ActMode = ConstModeC;
916 }
917 else /* !RelaxedMode */
918 ActMode = ConstMode;
919
920 /* Zahlensystem ermitteln/pruefen */
921
922 Base = RadixBase;
923 switch (ActMode)
924 {
925 case ConstModeIntel:
926 ch = as_toupper(pExpr[l - 1]);
927 if (DigitVal(ch, RadixBase) == -1)
928 {
929 for (BaseIdx = 0; BaseIdx < sizeof(BaseLetters) / sizeof(*BaseLetters); BaseIdx++)
930 if (ch == BaseLetters[BaseIdx])
931 {
932 Base = BaseVals[BaseIdx];
933 l--;
934 break;
935 }
936 }
937 break;
938 case ConstModeMoto:
939 for (BaseIdx = 0; BaseIdx < 3; BaseIdx++)
940 if (*pExpr == BaseIds[BaseIdx])
941 {
942 Base = BaseVals[BaseIdx];
943 pExpr++; l--;
944 break;
945 }
946 break;
947 case ConstModeC:
948 if (!strcmp(pExpr, "0"))
949 {
950 *pResult = True;
951 return 0;
952 }
953 if (*pExpr != '0') Base = RadixBase;
954 else if (l < 2) return -1;
955 else
956 {
957 pExpr++; l--;
958 ch = as_toupper(*pExpr);
959 if ((RadixBase != 10) && (DigitVal(ch, RadixBase) != -1))
960 Base = RadixBase;
961 else
962 switch (as_toupper(*pExpr))
963 {
964 case 'X':
965 pExpr++;
966 l--;
967 Base = 16;
968 break;
969 case 'B':
970 pExpr++;
971 l--;
972 Base = 2;
973 break;
974
975 /* in relaxed mode, treat pseudo octal constants like decimal: */
976
977 default:
978 {
979 const char *pRun;
980
981 for (pRun = pExpr; *pRun; pRun++)
982 if ((*pRun == '8') || (*pRun == '9'))
983 break;
984 Base = (RelaxedMode && *pRun) ? 10 : 8;
985 }
986 }
987 }
988 break;
989 case ConstModeWeird:
990 if (isdigit(*pExpr)) break;
991 if ((l < 2) || (pExpr[1] != '\''))
992 return -1;
993 switch (as_toupper(*pExpr))
994 {
995 case 'X':
996 case 'H':
997 Base = 16;
998 break;
999 case 'B':
1000 Base = 2;
1001 break;
1002 case 'O':
1003 Base = 8;
1004 break;
1005 default:
1006 return -1;
1007 }
1008 if ((pExpr[l - 1] == '\'') && (l >= 3))
1009 l -= 3;
1010 else if (ConstModeWeirdNoTerm)
1011 l -= 2;
1012 else
1013 return -1;
1014 pExpr += 2;
1015 break;
1016 }
1017
1018 if (!*pExpr)
1019 return -1;
1020
1021 if (ActMode == ConstModeIntel)
1022 {
1023 if ((*pExpr < '0') || (*pExpr > '9'))
1024 return -1;
1025 }
1026
1027 /* we may have decremented l, so do not run until string end */
1028
1029 while (l > 0)
1030 {
1031 Digit = DigitVal(as_toupper(*pExpr), Base);
1032 if (Digit == -1)
1033 return -1;
1034 Wert = Wert * Base + Digit;
1035 pExpr++; l--;
1036 }
1037
1038 if (NegFlag)
1039 Wert = -Wert;
1040
1041 /* post-processing, range check */
1042
1043 *pResult = RangeCheck(Wert, Typ);
1044 if (*pResult)
1045 return Wert;
1046 else if (HardRanges)
1047 {
1048 WrError(ErrNum_OverRange);
1049 return -1;
1050 }
1051 else
1052 {
1053 *pResult = True;
1054 WrError(ErrNum_WOverRange);
1055 return Wert&IntTypeDefs[(int)Typ].Mask;
1056 }
1057 }
1058
1059 /*****************************************************************************
1060 * Function: ConstFloatVal
1061 * Purpose: evaluate floating point constant
1062 * Result: value
1063 *****************************************************************************/
1064
ConstFloatVal(const char * pExpr,FloatType Typ,Boolean * pResult)1065 static Double ConstFloatVal(const char *pExpr, FloatType Typ, Boolean *pResult)
1066 {
1067 Double Erg;
1068 char *pEnd;
1069
1070 UNUSED(Typ);
1071
1072 if (*pExpr)
1073 {
1074 /* Some strtod() implementations interpret hex constants starting with '0x'. We
1075 don't want this here. Either 0x for hex constants is allowed, then it should
1076 have been parsed before by ConstIntVal(), or not, then we don't want the constant
1077 be stored as float. */
1078
1079 if ((strlen(pExpr) >= 2)
1080 && (pExpr[0] == '0')
1081 && (toupper(pExpr[1]) == 'X'))
1082 {
1083 Erg = 0;
1084 *pResult = False;
1085 }
1086
1087 else
1088 {
1089 Erg = strtod(pExpr, &pEnd);
1090 *pResult = (*pEnd == '\0');
1091 }
1092 }
1093 else
1094 {
1095 Erg = 0.0;
1096 *pResult = True;
1097 }
1098 return Erg;
1099 }
1100
1101 /*****************************************************************************
1102 * Function: ConstStringVal
1103 * Purpose: evaluate string constant
1104 * Result: value
1105 *****************************************************************************/
1106
ConstStringVal(const tStrComp * pExpr,TempResult * pDest,Boolean * pResult)1107 static void ConstStringVal(const tStrComp *pExpr, TempResult *pDest, Boolean *pResult)
1108 {
1109 String CopyStr;
1110 tStrComp Copy, Remainder;
1111 char *pPos, QuoteChar;
1112 int l, TLen;
1113
1114 StrCompMkTemp(&Copy, CopyStr);
1115 *pResult = False;
1116
1117 l = strlen(pExpr->Str);
1118 if (l < 2)
1119 return;
1120 switch (*pExpr->Str)
1121 {
1122 case '"':
1123 case '\'':
1124 QuoteChar = *pExpr->Str;
1125 if (pExpr->Str[l - 1] == QuoteChar)
1126 {
1127 if ('\'' == QuoteChar)
1128 pDest->Flags |= eSymbolFlag_StringSingleQuoted;
1129 break;
1130 }
1131 /* conditional fall-through */
1132 default:
1133 return;
1134 }
1135
1136 StrCompCopy(&Copy, pExpr);
1137 StrCompIncRefLeft(&Copy, 1);
1138 StrCompShorten(&Copy, 1);
1139
1140 /* go through source */
1141
1142 pDest->Typ = TempNone;
1143 pDest->Contents.Ascii.Length = 0;
1144 while (1)
1145 {
1146 pPos = strchr(Copy.Str, '\\');
1147 if (pPos)
1148 StrCompSplitRef(&Copy, &Remainder, &Copy, pPos);
1149
1150 /* " before \ -> not a simple string but something like "...." ... " */
1151
1152 if (strchr(Copy.Str, QuoteChar))
1153 return;
1154
1155 /* copy part up to next '\' verbatim: */
1156
1157 DynStringAppend(&pDest->Contents.Ascii, Copy.Str, strlen(Copy.Str));
1158
1159 /* are we done? If not, advance pointer to behind '\' */
1160
1161 if (!pPos)
1162 break;
1163 Copy = Remainder;
1164
1165 /* treat escaped section: stringification? */
1166
1167 if (*Copy.Str == '{')
1168 {
1169 TempResult t;
1170 char *pStr;
1171 String Str;
1172
1173 StrCompIncRefLeft(&Copy, 1);
1174
1175 /* cut out part in {...} */
1176
1177 pPos = QuotPos(Copy.Str, '}');
1178 if (!pPos)
1179 return;
1180 StrCompSplitRef(&Copy, &Remainder, &Copy, pPos);
1181 KillPrefBlanksStrCompRef(&Copy);
1182 KillPostBlanksStrComp(&Copy);
1183
1184 /* evaluate expression */
1185
1186 EvalStrExpression(&Copy, &t);
1187 if (t.Relocs)
1188 {
1189 WrStrErrorPos(ErrNum_NoRelocs, &Copy);
1190 FreeRelocs(&t.Relocs);
1191 *pResult = True;
1192 return;
1193 }
1194
1195 /* append result */
1196
1197 switch (t.Typ)
1198 {
1199 case TempInt:
1200 TLen = SysString(Str, sizeof(Str), t.Contents.Int, OutRadixBase, 0, False, HexStartCharacter);
1201 pStr = Str;
1202 break;
1203 case TempFloat:
1204 FloatString(Str, sizeof(Str), t.Contents.Float);
1205 pStr = Str;
1206 TLen = strlen(pStr);
1207 break;
1208 case TempString:
1209 pStr = t.Contents.Ascii.Contents;
1210 TLen = t.Contents.Ascii.Length;
1211 break;
1212 default:
1213 *pResult = True;
1214 return;
1215 }
1216 DynStringAppend(&pDest->Contents.Ascii, pStr, TLen);
1217 pDest->Flags |= t.Flags & eSymbolFlags_Promotable;
1218
1219 /* advance source pointer to behind '}' */
1220
1221 Copy = Remainder;
1222 }
1223
1224 /* simple character escape: */
1225
1226 else
1227 {
1228 char Res, *pNext = Copy.Str;
1229
1230 if (!ProcessBk(&pNext, &Res))
1231 return;
1232 DynStringAppend(&pDest->Contents.Ascii, &Res, 1);
1233 StrCompIncRefLeft(&Copy, pNext - Copy.Str);
1234 }
1235 }
1236
1237 pDest->Typ = TempString;
1238 *pResult = True;
1239 }
1240
1241
1242 static PSymbolEntry FindLocNode(
1243 #ifdef __PROTOS__
1244 const char *Name, TempType SearchType
1245 #endif
1246 );
1247
1248 static PSymbolEntry FindNode(
1249 #ifdef __PROTOS__
1250 const char *Name, TempType SearchType
1251 #endif
1252 );
1253
1254 /*!------------------------------------------------------------------------
1255 * \fn EvalResultClear(tEvalResult *pResult)
1256 * \brief reset all elements of EvalResult
1257 * ------------------------------------------------------------------------ */
1258
EvalResultClear(tEvalResult * pResult)1259 void EvalResultClear(tEvalResult *pResult)
1260 {
1261 pResult->OK = False;
1262 pResult->Flags = eSymbolFlag_None;
1263 pResult->AddrSpaceMask = 0;
1264 pResult->DataSize = eSymbolSizeUnknown;
1265 }
1266
1267 /*****************************************************************************
1268 * Function: EvalStrExpression
1269 * Purpose: evaluate expression
1270 * Result: implicitly in pErg
1271 *****************************************************************************/
1272
1273 #define LEAVE goto func_exit
1274
DeduceExpectTypeErrMsgMask(unsigned Mask,TempType ActType)1275 static tErrorNum DeduceExpectTypeErrMsgMask(unsigned Mask, TempType ActType)
1276 {
1277 switch (ActType)
1278 {
1279 case TempInt:
1280 switch (Mask)
1281 {
1282 case TempString:
1283 return ErrNum_StringButInt;
1284 /* int is convertible to float, so combinations are impossible: */
1285 case TempFloat:
1286 case TempFloat | TempString:
1287 default:
1288 return ErrNum_InternalError;
1289 }
1290 case TempFloat:
1291 switch (Mask)
1292 {
1293 case TempInt:
1294 return ErrNum_IntButFloat;
1295 case TempString:
1296 return ErrNum_StringButFloat;
1297 case TempInt | TempString:
1298 return ErrNum_StringOrIntButFloat;
1299 default:
1300 return ErrNum_InternalError;
1301 }
1302 case TempString:
1303 switch (Mask)
1304 {
1305 case TempInt:
1306 return ErrNum_IntButString;
1307 case TempFloat:
1308 return ErrNum_FloatButString;
1309 case TempInt | TempFloat:
1310 return ErrNum_IntOrFloatButString;
1311 default:
1312 return ErrNum_InternalError;
1313 }
1314 case TempReg:
1315 switch (Mask)
1316 {
1317 case TempInt:
1318 return ErrNum_ExpectInt;
1319 case TempString:
1320 return ErrNum_ExpectString;
1321 case TempInt | TempString:
1322 return ErrNum_ExpectIntOrString;
1323 case TempInt | TempFloat | TempString:
1324 return ErrNum_StringOrIntOrFloatButReg;
1325 default:
1326 return ErrNum_InternalError;
1327 }
1328 default:
1329 return ErrNum_InternalError;
1330 }
1331 }
1332
GetOpTypeMask(Byte TotMask,int OpIndex)1333 static Byte GetOpTypeMask(Byte TotMask, int OpIndex)
1334 {
1335 return (TotMask >> (OpIndex * 4)) & 15;
1336 }
1337
TryConvert(Byte TypeMask,TempType ActType,int OpIndex)1338 static Byte TryConvert(Byte TypeMask, TempType ActType, int OpIndex)
1339 {
1340 if (TypeMask & ActType)
1341 return 0 << (4 * OpIndex);
1342 if ((TypeMask & TempFloat) && (ActType == TempInt))
1343 return 1 << (4 * OpIndex);
1344 if ((TypeMask & TempInt) && (ActType == TempString))
1345 return 2 << (4 * OpIndex);
1346 if ((TypeMask & TempFloat) && (ActType == TempString))
1347 return (1|2) << (4 * OpIndex);
1348 return 255;
1349 }
1350
EvalStrExpression(const tStrComp * pExpr,TempResult * pErg)1351 void EvalStrExpression(const tStrComp *pExpr, TempResult *pErg)
1352 {
1353 const Operator *pOp;
1354 const Operator *FOps[OPERATOR_MAXCNT];
1355 LongInt FOpCnt = 0;
1356
1357 Boolean OK;
1358 tStrComp InArgs[3];
1359 TempResult InVals[3];
1360 int z1, cnt;
1361 char Save = '\0';
1362 sint LKlamm, RKlamm, WKlamm, zop;
1363 sint OpMax, OpPos = -1;
1364 Boolean InSgl, InDbl, NextEscaped, ThisEscaped;
1365 PFunction ValFunc;
1366 tStrComp CopyComp, STempComp;
1367 String CopyStr, stemp;
1368 char *KlPos, *zp, *pOpPos;
1369 const tFunction *pFunction;
1370 PRelocEntry TReloc;
1371 tSymbolFlags PromotedFlags;
1372 unsigned PromotedAddrSpaceMask;
1373 tSymbolSize PromotedDataSize;
1374
1375 ChkStack();
1376
1377 StrCompMkTemp(&CopyComp, CopyStr);
1378 StrCompMkTemp(&STempComp, stemp);
1379
1380 if (MakeDebug)
1381 fprintf(Debug, "Parse '%s'\n", pExpr->Str);
1382
1383 memset(InVals, 0, sizeof(InVals));
1384
1385 /* Annahme Fehler */
1386
1387 pErg->Typ = TempNone;
1388 pErg->Relocs = NULL;
1389 pErg->Flags = eSymbolFlag_None;
1390 pErg->AddrSpaceMask = 0;
1391 pErg->DataSize = eSymbolSizeUnknown;
1392
1393 StrCompCopy(&CopyComp, pExpr);
1394 KillPrefBlanksStrComp(&CopyComp);
1395 KillPostBlanksStrComp(&CopyComp);
1396
1397 /* sort out local symbols like - and +++. Do it now to get them out of the
1398 formula parser's way. */
1399
1400 ChkTmp2(CopyComp.Str, CopyComp.Str, FALSE);
1401 StrCompCopy(&STempComp, &CopyComp);
1402
1403 /* Programmzaehler ? */
1404
1405 if ((PCSymbol) && (!as_strcasecmp(CopyComp.Str, PCSymbol)))
1406 {
1407 pErg->Typ = TempInt;
1408 pErg->Contents.Int = EProgCounter();
1409 pErg->Relocs = NULL;
1410 pErg->AddrSpaceMask |= 1 << ActPC;
1411 LEAVE;
1412 }
1413
1414 /* Konstanten ? */
1415
1416 pErg->Contents.Int = ConstIntVal(CopyComp.Str, (IntType) (IntTypeCnt - 1), &OK);
1417 if (OK)
1418 {
1419 pErg->Typ = TempInt;
1420 pErg->Relocs = NULL;
1421 LEAVE;
1422 }
1423
1424 pErg->Contents.Float = ConstFloatVal(CopyComp.Str, Float80, &OK);
1425 if (OK)
1426 {
1427 pErg->Typ = TempFloat;
1428 pErg->Relocs = NULL;
1429 LEAVE;
1430 }
1431
1432 ConstStringVal(&CopyComp, pErg, &OK);
1433 if (OK)
1434 {
1435 pErg->Relocs = NULL;
1436 LEAVE;
1437 }
1438
1439 /* durch Codegenerator gegebene Konstanten ? */
1440
1441 pErg->Relocs = NULL;
1442 InternSymbol(CopyComp.Str, pErg);
1443 if (pErg->Typ != TempNone)
1444 LEAVE;
1445
1446 /* find out which operators *might* occur in expression */
1447
1448 OpMax = 0;
1449 LKlamm = 0;
1450 RKlamm = 0;
1451 WKlamm = 0;
1452 InSgl =
1453 InDbl =
1454 ThisEscaped =
1455 NextEscaped = False;
1456 for (pOp = Operators + 1; pOp->Id; pOp++)
1457 {
1458 pOpPos = (pOp->IdLen == 1) ? (strchr(CopyComp.Str, *pOp->Id)) : (strstr(CopyComp.Str, pOp->Id));
1459 if (pOpPos)
1460 FOps[FOpCnt++] = pOp;
1461 }
1462
1463 /* nach Operator hoechster Rangstufe ausserhalb Klammern suchen */
1464
1465 for (zp = CopyComp.Str; *zp; zp++, ThisEscaped = NextEscaped)
1466 {
1467 NextEscaped = False;
1468 switch (*zp)
1469 {
1470 case '(':
1471 if (!(InSgl || InDbl))
1472 LKlamm++;
1473 break;
1474 case ')':
1475 if (!(InSgl || InDbl))
1476 RKlamm++;
1477 break;
1478 case '{':
1479 if (!(InSgl || InDbl))
1480 WKlamm++;
1481 break;
1482 case '}':
1483 if (!(InSgl || InDbl))
1484 WKlamm--;
1485 break;
1486 case '"':
1487 if (!InSgl && !ThisEscaped)
1488 InDbl = !InDbl;
1489 break;
1490 case '\'':
1491 if (!InDbl && !ThisEscaped)
1492 {
1493 if (InSgl || !QualifyQuote || QualifyQuote(CopyComp.Str, zp))
1494 InSgl = !InSgl;
1495 }
1496 break;
1497 case '\\':
1498 if ((InDbl || InSgl) && !ThisEscaped)
1499 NextEscaped = True;
1500 break;
1501 default:
1502 if ((LKlamm == RKlamm) && (WKlamm == 0) && (!InSgl) && (!InDbl))
1503 {
1504 Boolean OpFnd = False;
1505 sint OpLen = 0, LocOpMax = 0;
1506
1507 for (zop = 0; zop < FOpCnt; zop++)
1508 {
1509 pOp = FOps[zop];
1510 if ((!strncmp(zp, pOp->Id, pOp->IdLen)) && (pOp->IdLen >= OpLen))
1511 {
1512 OpFnd = True;
1513 OpLen = pOp->IdLen;
1514 LocOpMax = pOp - Operators;
1515 if (Operators[LocOpMax].Priority >= Operators[OpMax].Priority)
1516 {
1517 OpMax = LocOpMax;
1518 OpPos = zp - CopyComp.Str;
1519 }
1520 }
1521 }
1522 if (OpFnd)
1523 zp += Operators[LocOpMax].IdLen - 1;
1524 }
1525 }
1526 }
1527
1528 /* Klammerfehler ? */
1529
1530 if (LKlamm != RKlamm)
1531 {
1532 WrStrErrorPos(ErrNum_BrackErr, &CopyComp);
1533 LEAVE;
1534 }
1535
1536 /* Operator gefunden ? */
1537
1538 if (OpMax)
1539 {
1540 int ThisArgCnt, CompLen, z, z2;
1541 Byte ThisOpMatch, BestOpMatch, BestOpMatchIdx, SumCombinations, TypeMask;
1542
1543 pOp = Operators + OpMax;
1544
1545 /* Minuszeichen sowohl mit einem als auch 2 Operanden */
1546
1547 if (!strcmp(pOp->Id, "-"))
1548 {
1549 if (!OpPos)
1550 pOp = &MinusMonadicOperator;
1551 }
1552
1553 /* Operandenzahl pruefen */
1554
1555 CompLen = strlen(CopyComp.Str);
1556 if (CompLen <= 1)
1557 ThisArgCnt = 0;
1558 else if (!OpPos || (OpPos == (int)strlen(CopyComp.Str) - 1))
1559 ThisArgCnt = 1;
1560 else
1561 ThisArgCnt = 2;
1562 if (!ChkArgCntExtPos(ThisArgCnt, pOp->Dyadic ? 2 : 1, pOp->Dyadic ? 2 : 1, &CopyComp.Pos))
1563 LEAVE;
1564
1565 /* Teilausdruecke rekursiv auswerten */
1566
1567 Save = StrCompSplitRef(&InArgs[0], &InArgs[1], &CopyComp, CopyComp.Str + OpPos);
1568 StrCompIncRefLeft(&InArgs[1], strlen(pOp->Id) - 1);
1569 EvalStrExpression(&InArgs[1], &InVals[1]);
1570 if (pOp->Dyadic)
1571 EvalStrExpression(&InArgs[0], &InVals[0]);
1572 else if (InVals[1].Typ == TempFloat)
1573 {
1574 InVals[0].Typ = TempFloat;
1575 InVals[0].Contents.Float = 0.0;
1576 }
1577 else
1578 {
1579 InVals[0].Typ = TempInt;
1580 InVals[0].Contents.Int = 0;
1581 InVals[0].Relocs = NULL;
1582 }
1583 CopyComp.Str[OpPos] = Save;
1584
1585 /* Abbruch, falls dabei Fehler */
1586
1587 if ((InVals[0].Typ == TempNone) || (InVals[1].Typ == TempNone))
1588 LEAVE;
1589
1590 /* relokatible Symbole nur fuer + und - erlaubt */
1591
1592 if ((OpMax != 12) && (OpMax != 13) && (InVals[0].Relocs || InVals[1].Relocs))
1593 {
1594 WrStrErrorPos(ErrNum_NoRelocs, &CopyComp);
1595 LEAVE;
1596 }
1597
1598 /* see whether data types match operator's restrictions: */
1599
1600 BestOpMatch = 255; BestOpMatchIdx = OPERATOR_MAXCOMB;
1601 SumCombinations = 0;
1602 for (z = 0; z < OPERATOR_MAXCOMB; z++)
1603 {
1604 if (!pOp->TypeCombinations[z])
1605 break;
1606 SumCombinations |= pOp->TypeCombinations[z];
1607
1608 ThisOpMatch = 0;
1609 for (z2 = pOp->Dyadic ? 0 : 1; z2 < 2; z2++)
1610 ThisOpMatch |= TryConvert(GetOpTypeMask(pOp->TypeCombinations[z], z2), InVals[z2].Typ, z2);
1611 if (ThisOpMatch < BestOpMatch)
1612 {
1613 BestOpMatch = ThisOpMatch;
1614 BestOpMatchIdx = z;
1615 }
1616 if (!BestOpMatch)
1617 break;
1618 }
1619
1620 /* did not find a way to satisfy restrictions, even by conversions? */
1621
1622 if (BestOpMatch >= 255)
1623 {
1624 for (z2 = pOp->Dyadic ? 0 : 1; z2 < 2; z2++)
1625 {
1626 TypeMask = GetOpTypeMask(SumCombinations, z2);
1627 if (!(TypeMask & InVals[z2].Typ))
1628 WrStrErrorPos(DeduceExpectTypeErrMsgMask(TypeMask, InVals[z2].Typ), &InArgs[z2]);
1629 }
1630 LEAVE;
1631 }
1632
1633 /* necessary conversions: */
1634
1635 for (z2 = pOp->Dyadic ? 0 : 1; z2 < 2; z2++)
1636 {
1637 TypeMask = (BestOpMatch >> (z2 * 4)) & 15;
1638 if (TypeMask & 2) /* String -> Int */
1639 TempResultToInt(&InVals[z2]);
1640 if (TypeMask & 1) /* Int -> Float */
1641 TempResultToFloat(&InVals[z2]);
1642 }
1643
1644 /* actual operation */
1645
1646 (void)BestOpMatchIdx;
1647 pOp->pFunc(pErg, &InVals[0], &InVals[1]);
1648 LEAVE;
1649 } /* if (OpMax) */
1650
1651 /* kein Operator gefunden: Klammerausdruck ? */
1652
1653 if (LKlamm != 0)
1654 {
1655 tStrComp FName, FArg, Remainder;
1656
1657 /* erste Klammer suchen, Funktionsnamen abtrennen */
1658
1659 KlPos = strchr(CopyComp.Str, '(');
1660
1661 /* Funktionsnamen abschneiden */
1662
1663 StrCompSplitRef(&FName, &FArg, &CopyComp, KlPos);
1664 StrCompShorten(&FArg, 1);
1665 KillPostBlanksStrComp(&FName);
1666
1667 /* Nullfunktion: nur Argument */
1668
1669 if (*FName.Str == '\0')
1670 {
1671 EvalStrExpression(&FArg, &InVals[0]);
1672 *pErg = InVals[0];
1673 LEAVE;
1674 }
1675
1676 /* selbstdefinierte Funktion ? */
1677
1678 ValFunc = FindFunction(FName.Str);
1679 if (ValFunc)
1680 {
1681 String CompArgStr;
1682 tStrComp CompArg;
1683
1684 PromotedFlags = eSymbolFlag_None;
1685 PromotedAddrSpaceMask = 0;
1686 PromotedDataSize = eSymbolSizeUnknown;
1687 StrCompMkTemp(&CompArg, CompArgStr);
1688 strmaxcpy(CompArg.Str, ValFunc->Definition, STRINGSIZE);
1689 for (z1 = 1; z1 <= ValFunc->ArguCnt; z1++)
1690 {
1691 if (!*FArg.Str)
1692 {
1693 WrError(ErrNum_InvFuncArgCnt);
1694 LEAVE;
1695 }
1696
1697 KlPos = QuotPos(FArg.Str, ',');
1698 if (KlPos)
1699 StrCompSplitRef(&FArg, &Remainder, &FArg, KlPos);
1700
1701 EvalStrExpression(&FArg, &InVals[0]);
1702 if (InVals[0].Relocs)
1703 {
1704 WrStrErrorPos(ErrNum_NoRelocs, &FArg);
1705 FreeRelocs(&InVals[0].Relocs);
1706 return;
1707 }
1708 PromotedFlags |= InVals[0].Flags & eSymbolFlags_Promotable;
1709 PromotedAddrSpaceMask |= InVals[0].AddrSpaceMask;
1710 if (PromotedDataSize == eSymbolSizeUnknown) PromotedDataSize = InVals[0].DataSize;
1711
1712 if (KlPos)
1713 FArg = Remainder;
1714 else
1715 StrCompReset(&FArg);
1716
1717 strmaxcpy(stemp, "(", STRINGSIZE);
1718 if (TempResultToPlainString(stemp + 1, &InVals[0], STRINGSIZE - 1))
1719 LEAVE;
1720 strmaxcat(stemp,")", STRINGSIZE);
1721 ExpandLine(stemp, z1, CompArg.Str, sizeof(CompArgStr));
1722 }
1723 if (*FArg.Str)
1724 {
1725 WrError(ErrNum_InvFuncArgCnt);
1726 LEAVE;
1727 }
1728 EvalStrExpression(&CompArg, pErg);
1729 pErg->Flags |= PromotedFlags;
1730 pErg->AddrSpaceMask |= PromotedAddrSpaceMask;
1731 if (pErg->DataSize == eSymbolSizeUnknown) pErg->DataSize = PromotedDataSize;
1732 LEAVE;
1733 }
1734
1735 /* hier einmal umwandeln ist effizienter */
1736
1737 NLS_UpString(FName.Str);
1738
1739 /* symbolbezogene Funktionen */
1740
1741 if (!strcmp(FName.Str, "SYMTYPE"))
1742 {
1743 pErg->Typ = TempInt;
1744 pErg->Contents.Int = GetSymbolType(&FArg);
1745 LEAVE;
1746 }
1747
1748 else if (!strcmp(FName.Str, "DEFINED"))
1749 {
1750 pErg->Typ = TempInt;
1751 pErg->Contents.Int = !!IsSymbolDefined(&FArg);
1752 LEAVE;
1753 }
1754
1755 else if (!strcmp(FName.Str, "ASSUMEDVAL"))
1756 {
1757 unsigned IdxAssume;
1758
1759 for (IdxAssume = 0; IdxAssume < ASSUMERecCnt; IdxAssume++)
1760 if (!as_strcasecmp(FArg.Str, pASSUMERecs[IdxAssume].Name))
1761 {
1762 pErg->Typ = TempInt;
1763 pErg->Contents.Int = *(pASSUMERecs[IdxAssume].Dest);
1764 LEAVE;
1765 }
1766 WrStrErrorPos(ErrNum_SymbolUndef, &FArg);
1767 LEAVE;
1768 }
1769
1770 /* Unterausdruck auswerten (interne Funktionen maxmimal mit drei Argumenten) */
1771
1772 cnt = 0;
1773 PromotedFlags = eSymbolFlag_None;
1774 PromotedAddrSpaceMask = 0;
1775 PromotedDataSize = eSymbolSizeUnknown;
1776 do
1777 {
1778 zp = QuotPos(FArg.Str, ',');
1779 if (zp)
1780 StrCompSplitRef(&InArgs[cnt], &Remainder, &FArg, zp);
1781 else
1782 InArgs[cnt] = FArg;
1783 if (cnt < 3)
1784 {
1785 EvalStrExpression(&InArgs[cnt], &InVals[cnt]);
1786 if (InVals[cnt].Typ == TempNone)
1787 LEAVE;
1788 TReloc = InVals[cnt].Relocs;
1789 }
1790 else
1791 {
1792 WrError(ErrNum_InvFuncArgCnt);
1793 LEAVE;
1794 }
1795 if (TReloc)
1796 {
1797 WrStrErrorPos(ErrNum_NoRelocs, &InArgs[cnt]);
1798 FreeRelocs(&TReloc);
1799 LEAVE;
1800 }
1801 if (zp)
1802 FArg = Remainder;
1803 PromotedFlags |= InVals[cnt].Flags & eSymbolFlags_Promotable;
1804 PromotedAddrSpaceMask |= InVals[cnt].AddrSpaceMask;
1805 if (PromotedDataSize == eSymbolSizeUnknown) PromotedDataSize = InVals[0].DataSize;
1806 cnt++;
1807 }
1808 while (zp);
1809
1810 /* search function */
1811
1812 for (pFunction = Functions; pFunction->pName; pFunction++)
1813 if (!strcmp(FName.Str, pFunction->pName))
1814 break;
1815 if (!pFunction->pName)
1816 {
1817 WrStrErrorPos(ErrNum_UnknownFunc, &FName);
1818 LEAVE;
1819 }
1820
1821 /* argument checking */
1822
1823 if ((cnt < pFunction->MinNumArgs) || (cnt > pFunction->MaxNumArgs))
1824 {
1825 WrError(ErrNum_InvFuncArgCnt);
1826 LEAVE;
1827 }
1828 for (z1 = 0; z1 < cnt; z1++)
1829 {
1830 if ((InVals[z1].Typ == TempInt) && (!(pFunction->ArgTypes[z1] & (1 << TempInt))))
1831 TempResultToFloat(&InVals[z1]);
1832 if (!(pFunction->ArgTypes[z1] & (1 << InVals[z1].Typ)))
1833 {
1834 WrStrErrorPos(DeduceExpectTypeErrMsgMask(pFunction->ArgTypes[z1], InVals[z1].Typ), &InArgs[z1]);
1835 LEAVE;
1836 }
1837 }
1838 pFunction->pFunc(pErg, InVals, cnt);
1839 pErg->Flags |= PromotedFlags;
1840 pErg->AddrSpaceMask |= PromotedAddrSpaceMask;
1841 if (pErg->DataSize == eSymbolSizeUnknown) pErg->DataSize = PromotedDataSize;
1842
1843 LEAVE;
1844 }
1845
1846 /* nichts dergleichen, dann einfaches Symbol: urspruenglichen Wert wieder
1847 herstellen, dann Pruefung auf $$-temporaere Symbole */
1848
1849 StrCompCopy(&CopyComp, &STempComp);
1850 KillPrefBlanksStrComp(&CopyComp);
1851 KillPostBlanksStrComp(&CopyComp);
1852
1853 ChkTmp1(CopyComp.Str, FALSE);
1854
1855 /* interne Symbole ? */
1856
1857 if (!as_strcasecmp(CopyComp.Str, "MOMFILE"))
1858 {
1859 pErg->Typ = TempString;
1860 CString2DynString(&pErg->Contents.Ascii, CurrFileName);
1861 LEAVE;
1862 }
1863
1864 if (!as_strcasecmp(CopyComp.Str, "MOMLINE"))
1865 {
1866 pErg->Typ = TempInt;
1867 pErg->Contents.Int = CurrLine;
1868 LEAVE;
1869 }
1870
1871 if (!as_strcasecmp(CopyComp.Str, "MOMPASS"))
1872 {
1873 pErg->Typ = TempInt;
1874 pErg->Contents.Int = PassNo;
1875 LEAVE;
1876 }
1877
1878 if (!as_strcasecmp(CopyComp.Str, "MOMSECTION"))
1879 {
1880 pErg->Typ = TempString;
1881 CString2DynString(&pErg->Contents.Ascii, GetSectionName(MomSectionHandle));
1882 LEAVE;
1883 }
1884
1885 if (!as_strcasecmp(CopyComp.Str, "MOMSEGMENT"))
1886 {
1887 pErg->Typ = TempString;
1888 CString2DynString(&pErg->Contents.Ascii, SegNames[ActPC]);
1889 LEAVE;
1890 }
1891
1892 /* plain symbol */
1893
1894 LookupSymbol(&CopyComp, pErg, True, TempAll);
1895
1896 func_exit:
1897
1898 for (z1 = 0; z1 < 3; z1++)
1899 if (InVals[z1].Relocs)
1900 FreeRelocs(&InVals[z1].Relocs);
1901 }
1902
EvalExpression(const char * pExpr,TempResult * pErg)1903 void EvalExpression(const char *pExpr, TempResult *pErg)
1904 {
1905 tStrComp Expr;
1906
1907 StrCompMkTemp(&Expr, (char*)pExpr);
1908 EvalStrExpression(&Expr, pErg);
1909 }
1910
EvalStrIntExpressionWithResult(const tStrComp * pComp,IntType Type,tEvalResult * pResult)1911 LargeInt EvalStrIntExpressionWithResult(const tStrComp *pComp, IntType Type, tEvalResult *pResult)
1912 {
1913 TempResult t;
1914 LargeInt Result;
1915
1916 EvalResultClear(pResult);
1917
1918 EvalStrExpression(pComp, &t);
1919 SetRelocs(t.Relocs);
1920
1921 switch (t.Typ)
1922 {
1923 case TempInt:
1924 Result = t.Contents.Int;
1925 pResult->Flags = t.Flags;
1926 pResult->AddrSpaceMask = t.AddrSpaceMask;
1927 pResult->DataSize = t.DataSize;
1928 break;
1929 case TempString:
1930 {
1931 int l = t.Contents.Ascii.Length;
1932
1933 if ((l > 0) && (l <= 4))
1934 {
1935 char *pRun;
1936 Byte Digit;
1937
1938 Result = 0;
1939 for (pRun = t.Contents.Ascii.Contents;
1940 pRun < t.Contents.Ascii.Contents + l;
1941 pRun++)
1942 {
1943 Digit = (usint) *pRun;
1944 Result = (Result << 8) | CharTransTable[Digit & 0xff];
1945 }
1946 pResult->Flags = t.Flags;
1947 pResult->AddrSpaceMask = t.AddrSpaceMask;
1948 pResult->DataSize = t.DataSize;
1949 break;
1950 }
1951 }
1952 /* else fall-through */
1953 default:
1954 if (t.Typ != TempNone)
1955 WrStrErrorPos(DeduceExpectTypeErrMsgMask(TempInt | TempString, t.Typ), pComp);
1956 FreeRelocs(&LastRelocs);
1957 return -1;
1958 }
1959
1960 if (mFirstPassUnknown(t.Flags))
1961 Result &= IntTypeDefs[(int)Type].Mask;
1962
1963 if (!RangeCheck(Result, Type))
1964 {
1965 if (HardRanges)
1966 {
1967 FreeRelocs(&LastRelocs);
1968 WrStrErrorPos(ErrNum_OverRange, pComp);
1969 return -1;
1970 }
1971 else
1972 {
1973 WrStrErrorPos(ErrNum_WOverRange, pComp);
1974 pResult->OK = True;
1975 return Result & IntTypeDefs[(int)Type].Mask;
1976 }
1977 }
1978 else
1979 {
1980 pResult->OK = True;
1981 return Result;
1982 }
1983 }
1984
EvalStrIntExpressionWithFlags(const tStrComp * pComp,IntType Type,Boolean * pResult,tSymbolFlags * pFlags)1985 LargeInt EvalStrIntExpressionWithFlags(const tStrComp *pComp, IntType Type, Boolean *pResult, tSymbolFlags *pFlags)
1986 {
1987 tEvalResult EvalResult;
1988 LargeInt Result = EvalStrIntExpressionWithResult(pComp, Type, &EvalResult);
1989
1990 *pResult = EvalResult.OK;
1991 if (pFlags)
1992 *pFlags = EvalResult.Flags;
1993 return Result;
1994 }
1995
EvalStrIntExpression(const tStrComp * pComp,IntType Type,Boolean * pResult)1996 LargeInt EvalStrIntExpression(const tStrComp *pComp, IntType Type, Boolean *pResult)
1997 {
1998 tEvalResult EvalResult;
1999 LargeInt Result = EvalStrIntExpressionWithResult(pComp, Type, &EvalResult);
2000
2001 *pResult = EvalResult.OK;
2002 return Result;
2003 }
2004
EvalStrIntExpressionOffsWithResult(const tStrComp * pExpr,int Offset,IntType Type,tEvalResult * pResult)2005 LargeInt EvalStrIntExpressionOffsWithResult(const tStrComp *pExpr, int Offset, IntType Type, tEvalResult *pResult)
2006 {
2007 if (Offset)
2008 {
2009 tStrComp Comp;
2010
2011 StrCompRefRight(&Comp, pExpr, Offset);
2012 return EvalStrIntExpressionWithResult(&Comp, Type, pResult);
2013 }
2014 else
2015 return EvalStrIntExpressionWithResult(pExpr, Type, pResult);
2016 }
2017
EvalStrIntExpressionOffsWithFlags(const tStrComp * pComp,int Offset,IntType Type,Boolean * pResult,tSymbolFlags * pFlags)2018 LargeInt EvalStrIntExpressionOffsWithFlags(const tStrComp *pComp, int Offset, IntType Type, Boolean *pResult, tSymbolFlags *pFlags)
2019 {
2020 tEvalResult EvalResult;
2021 LargeInt Result = EvalStrIntExpressionOffsWithResult(pComp, Offset, Type, &EvalResult);
2022
2023 *pResult = EvalResult.OK;
2024 if (pFlags)
2025 *pFlags = EvalResult.Flags;
2026 return Result;
2027 }
2028
EvalStrIntExpressionOffs(const tStrComp * pComp,int Offset,IntType Type,Boolean * pResult)2029 LargeInt EvalStrIntExpressionOffs(const tStrComp *pComp, int Offset, IntType Type, Boolean *pResult)
2030 {
2031 tEvalResult EvalResult;
2032 LargeInt Result = EvalStrIntExpressionOffsWithResult(pComp, Offset, Type, &EvalResult);
2033
2034 *pResult = EvalResult.OK;
2035 return Result;
2036 }
2037
EvalStrFloatExpressionWithResult(const tStrComp * pExpr,FloatType Type,tEvalResult * pResult)2038 Double EvalStrFloatExpressionWithResult(const tStrComp *pExpr, FloatType Type, tEvalResult *pResult)
2039 {
2040 TempResult t;
2041
2042 EvalResultClear(pResult);
2043
2044 EvalStrExpression(pExpr, &t);
2045 switch (t.Typ)
2046 {
2047 case TempNone:
2048 return -1;
2049 case TempInt:
2050 t.Contents.Float = t.Contents.Int;
2051 pResult->Flags = t.Flags;
2052 pResult->AddrSpaceMask = t.AddrSpaceMask;
2053 pResult->DataSize = t.DataSize;
2054 break;
2055 case TempString:
2056 {
2057 WrStrErrorPos(ErrNum_FloatButString, pExpr);
2058 return -1;
2059 }
2060 default:
2061 break;
2062 }
2063
2064 if (!FloatRangeCheck(t.Contents.Float, Type))
2065 {
2066 WrStrErrorPos(ErrNum_OverRange, pExpr);
2067 return -1;
2068 }
2069
2070 pResult->OK = True;
2071 return t.Contents.Float;
2072 }
2073
EvalStrFloatExpression(const tStrComp * pExpr,FloatType Type,Boolean * pResult)2074 Double EvalStrFloatExpression(const tStrComp *pExpr, FloatType Type, Boolean *pResult)
2075 {
2076 Double Ret;
2077 tEvalResult Result;
2078
2079 Ret = EvalStrFloatExpressionWithResult(pExpr, Type, &Result);
2080 *pResult = Result.OK;
2081 return Ret;
2082 }
2083
EvalStrStringExpressionWithResult(const tStrComp * pExpr,tEvalResult * pResult,char * pEvalResult)2084 void EvalStrStringExpressionWithResult(const tStrComp *pExpr, tEvalResult *pResult, char *pEvalResult)
2085 {
2086 TempResult t;
2087
2088 EvalResultClear(pResult);
2089
2090 EvalStrExpression(pExpr, &t);
2091 if (t.Typ != TempString)
2092 {
2093 *pEvalResult = '\0';
2094 if (t.Typ != TempNone)
2095 {
2096 if (mFirstPassUnknown(t.Flags))
2097 {
2098 *pEvalResult = '\0';
2099 pResult->Flags = t.Flags;
2100 pResult->AddrSpaceMask = t.AddrSpaceMask;
2101 pResult->DataSize = t.DataSize;
2102 pResult->OK = True;
2103 }
2104 else
2105 WrStrErrorPos(DeduceExpectTypeErrMsgMask(TempString, t.Typ), pExpr);
2106 }
2107 }
2108 else
2109 {
2110 DynString2CString(pEvalResult, &t.Contents.Ascii, STRINGSIZE);
2111 pResult->Flags = t.Flags;
2112 pResult->AddrSpaceMask = t.AddrSpaceMask;
2113 pResult->DataSize = t.DataSize;
2114 pResult->OK = True;
2115 }
2116 }
2117
EvalStrStringExpression(const tStrComp * pExpr,Boolean * pResult,char * pEvalResult)2118 void EvalStrStringExpression(const tStrComp *pExpr, Boolean *pResult, char *pEvalResult)
2119 {
2120 tEvalResult Result;
2121
2122 EvalStrStringExpressionWithResult(pExpr, &Result, pEvalResult);
2123 *pResult = Result.OK;
2124 }
2125
2126 /*!------------------------------------------------------------------------
2127 * \fn EvalStrRegExpressionWithResult(const struct sStrComp *pExpr, struct sRegDescr *pResult, struct sEvalResult *pEvalResult, Boolean IssueErrors)
2128 * \brief retrieve/evaluate register expression
2129 * \param pExpr source code expression
2130 * \param pResult retrieved register
2131 * \param pEvalResult success flag, symbol size & flags
2132 * \param IssueErrors print errors at all?
2133 * \return occured error
2134 * ------------------------------------------------------------------------ */
2135
ExpandAndFindNode(const struct sStrComp * pComp,TempType SearchType)2136 PSymbolEntry ExpandAndFindNode(const struct sStrComp *pComp, TempType SearchType)
2137 {
2138 PSymbolEntry pEntry;
2139 String ExpName;
2140 const char *pKlPos;
2141
2142 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pComp))
2143 return NULL;
2144
2145 /* just [...] without symbol name itself is not valid */
2146
2147 pKlPos = strchr(ExpName, '[');
2148 if ((pKlPos == ExpName) || (ChkSymbNameUpTo(ExpName, pKlPos) != pKlPos))
2149 return NULL;
2150
2151 pEntry = FindLocNode(ExpName, SearchType);
2152 if (!pEntry)
2153 pEntry = FindNode(ExpName, SearchType);
2154 return pEntry;
2155 }
2156
EvalStrRegExpressionWithResult(const struct sStrComp * pExpr,tRegDescr * pResult,tEvalResult * pEvalResult)2157 tErrorNum EvalStrRegExpressionWithResult(const struct sStrComp *pExpr, tRegDescr *pResult, tEvalResult *pEvalResult)
2158 {
2159 PSymbolEntry pEntry;
2160
2161 EvalResultClear(pEvalResult);
2162
2163 pEntry = ExpandAndFindNode(pExpr, TempReg);
2164 if (!pEntry)
2165 return ErrNum_SymbolUndef;
2166
2167 pEntry->Used = True;
2168 pEvalResult->DataSize = pEntry->SymSize;
2169
2170 if (pEntry->SymWert.Typ != TempReg)
2171 return ErrNum_ExpectReg;
2172 *pResult = pEntry->SymWert.Contents.RegDescr;
2173
2174 if (pEntry->SymWert.Contents.RegDescr.Dissect != DissectReg)
2175 return ErrNum_RegWrongTarget;
2176
2177 pEvalResult->OK = True;
2178 return ErrNum_None;
2179 }
2180
2181 /*!------------------------------------------------------------------------
2182 * \fn EvalStrRegExpressionAsOperand(const tStrComp *pArg, struct sRegDescr *pResult, struct sEvalResult *pEvalResult, tSymbolSize ReqSize, Boolean MustBeReg)
2183 * \brief check for possible register in instruction operand
2184 * \param pArg source argument
2185 * \param ReqSize possible fixed operand size
2186 * \param MustBeReg operand cannot be anything else but register
2187 * \return eIsReg: argument is a register
2188 eIsNoReg: argument is no register
2189 eRegAbort: argument is faulty, abort anyway (only if !MustBeReg)
2190 * ------------------------------------------------------------------------ */
2191
EvalStrRegExpressionAsOperand(const tStrComp * pArg,struct sRegDescr * pResult,struct sEvalResult * pEvalResult,tSymbolSize ReqSize,Boolean MustBeReg)2192 tRegEvalResult EvalStrRegExpressionAsOperand(const tStrComp *pArg, struct sRegDescr *pResult, struct sEvalResult *pEvalResult, tSymbolSize ReqSize, Boolean MustBeReg)
2193 {
2194 tErrorNum ErrorNum;
2195
2196 ErrorNum = EvalStrRegExpressionWithResult(pArg, pResult, pEvalResult);
2197 if (pEvalResult->OK && (ReqSize != eSymbolSizeUnknown) && (pEvalResult->DataSize != ReqSize))
2198 {
2199 pEvalResult->OK = False;
2200 ErrorNum = ErrNum_InvOpSize;
2201 }
2202 switch (ErrorNum)
2203 {
2204 case ErrNum_None:
2205 return eIsReg;
2206 case ErrNum_SymbolUndef:
2207 if (MustBeReg)
2208 {
2209 if (PassNo <= MaxSymPass)
2210 {
2211 pResult->Reg = 0;
2212 pResult->Dissect = NULL;
2213 Repass = True;
2214 return eIsReg;
2215 }
2216 else
2217 {
2218 WrStrErrorPos(ErrNum_InvReg, pArg);
2219 return eIsNoReg;
2220 }
2221 }
2222 else
2223 return eIsNoReg;
2224 case ErrNum_ExpectReg:
2225 if (MustBeReg)
2226 WrStrErrorPos(ErrorNum, pArg);
2227 return eIsNoReg;
2228 break;
2229 default:
2230 WrStrErrorPos(ErrorNum, pArg);
2231 return MustBeReg ? eIsNoReg : eRegAbort;
2232 }
2233 }
2234
2235
2236 /*!------------------------------------------------------------------------
2237 * \fn GetIntelSuffix(unsigned Radix)
2238 * \brief return Intel-style suffix letter fitting to number system
2239 * \param Radix req'd number system
2240 * \return * to suffix string (may be empty)
2241 * ------------------------------------------------------------------------ */
2242
GetIntelSuffix(unsigned Radix)2243 const char *GetIntelSuffix(unsigned Radix)
2244 {
2245 unsigned BaseIdx;
2246
2247 for (BaseIdx = 0; BaseIdx < sizeof(BaseLetters) / sizeof(*BaseLetters); BaseIdx++)
2248 if (Radix == BaseVals[BaseIdx])
2249 {
2250 static char Result[2] = { '\0', '\0' };
2251
2252 Result[0] = BaseLetters[BaseIdx] + (HexStartCharacter - 'A');
2253 return Result;
2254 }
2255 return "";
2256 }
2257
2258
FreeSymbolEntry(PSymbolEntry * Node,Boolean Destroy)2259 static void FreeSymbolEntry(PSymbolEntry *Node, Boolean Destroy)
2260 {
2261 PCrossRef Lauf;
2262
2263 if ((*Node)->Tree.Name)
2264 {
2265 free((*Node)->Tree.Name);
2266 (*Node)->Tree.Name = NULL;
2267 }
2268
2269 if ((*Node)->SymWert.Typ == TempString)
2270 free((*Node)->SymWert.Contents.String.Contents);
2271
2272 while ((*Node)->RefList)
2273 {
2274 Lauf = (*Node)->RefList->Next;
2275 free((*Node)->RefList);
2276 (*Node)->RefList = Lauf;
2277 }
2278
2279 FreeRelocs(&((*Node)->Relocs));
2280
2281 if (Destroy)
2282 {
2283 free(*Node);
2284 Node = NULL;
2285 }
2286 }
2287
2288 static char *serr, *snum;
2289 typedef struct
2290 {
2291 Boolean MayChange, DoCross;
2292 } TEnterStruct, *PEnterStruct;
2293
SymbolAdder(PTree * PDest,PTree Neu,void * pData)2294 static Boolean SymbolAdder(PTree *PDest, PTree Neu, void *pData)
2295 {
2296 PSymbolEntry NewEntry = (PSymbolEntry)Neu, *Node;
2297 PEnterStruct EnterStruct = (PEnterStruct) pData;
2298
2299 /* added to an empty leaf ? */
2300
2301 if (!PDest)
2302 {
2303 NewEntry->Defined = True;
2304 NewEntry->Used = False;
2305 NewEntry->Changeable = EnterStruct->MayChange;
2306 NewEntry->RefList = NULL;
2307 if (EnterStruct->DoCross)
2308 {
2309 NewEntry->FileNum = GetFileNum(CurrFileName);
2310 NewEntry->LineNum = CurrLine;
2311 }
2312 return True;
2313 }
2314
2315 /* replace en entry: check for validity */
2316
2317 Node = (PSymbolEntry*)PDest;
2318
2319 /* tried to redefine a symbol with EQU ? */
2320
2321 if (((*Node)->Defined) && (!(*Node)->Changeable) && (!EnterStruct->MayChange))
2322 {
2323 strmaxcpy(serr, (*Node)->Tree.Name, STRINGSIZE);
2324 if (EnterStruct->DoCross)
2325 as_snprcatf(serr, STRINGSIZE, ",%s %s:%ld",
2326 getmessage(Num_PrevDefMsg),
2327 GetFileName((*Node)->FileNum), (long)((*Node)->LineNum));
2328 WrXError(ErrNum_DoubleDef, serr);
2329 FreeSymbolEntry(&NewEntry, TRUE);
2330 return False;
2331 }
2332
2333 /* tried to reassign a constant (EQU) a value with SET and vice versa ? */
2334
2335 else if ( ((*Node)->Defined) && (EnterStruct->MayChange != (*Node)->Changeable) )
2336 {
2337 strmaxcpy(serr, (*Node)->Tree.Name, STRINGSIZE);
2338 if (EnterStruct->DoCross)
2339 as_snprcatf(serr, STRINGSIZE, ",%s %s:%ld",
2340 getmessage(Num_PrevDefMsg),
2341 GetFileName((*Node)->FileNum), (long)((*Node)->LineNum));
2342 WrXError((*Node)->Changeable ? ErrNum_VariableRedefinedAsConstant : ErrNum_ConstantRedefinedAsVariable, serr);
2343 FreeSymbolEntry(&NewEntry, TRUE);
2344 return False;
2345 }
2346
2347 else
2348 {
2349 if (!EnterStruct->MayChange)
2350 {
2351 if ((NewEntry->SymWert.Typ != (*Node)->SymWert.Typ)
2352 || ((NewEntry->SymWert.Typ == TempString) && (strlencmp(NewEntry->SymWert.Contents.String.Contents, NewEntry->SymWert.Contents.String.Length, (*Node)->SymWert.Contents.String.Contents, (*Node)->SymWert.Contents.String.Length)))
2353 || ((NewEntry->SymWert.Typ == TempFloat ) && (NewEntry->SymWert.Contents.FWert != (*Node)->SymWert.Contents.FWert))
2354 || ((NewEntry->SymWert.Typ == TempInt ) && (NewEntry->SymWert.Contents.IWert != (*Node)->SymWert.Contents.IWert)))
2355 {
2356 if ((!Repass) && (JmpErrors>0))
2357 {
2358 if (ThrowErrors)
2359 ErrorCount -= JmpErrors;
2360 JmpErrors = 0;
2361 }
2362 Repass = True;
2363 if ((MsgIfRepass) && (PassNo >= PassNoForMessage))
2364 {
2365 strmaxcpy(serr, Neu->Name, STRINGSIZE);
2366 if (Neu->Attribute != -1)
2367 {
2368 strmaxcat(serr, "[", STRINGSIZE);
2369 strmaxcat(serr, GetSectionName(Neu->Attribute), STRINGSIZE);
2370 strmaxcat(serr, "]", STRINGSIZE);
2371 }
2372 WrXError(ErrNum_PhaseErr, serr);
2373 }
2374 }
2375 }
2376 if (EnterStruct->DoCross)
2377 {
2378 NewEntry->LineNum = (*Node)->LineNum;
2379 NewEntry->FileNum = (*Node)->FileNum;
2380 }
2381 NewEntry->RefList = (*Node)->RefList;
2382 (*Node)->RefList = NULL;
2383 NewEntry->Defined = True;
2384 NewEntry->Used = (*Node)->Used;
2385 NewEntry->Changeable = EnterStruct->MayChange;
2386 FreeSymbolEntry(Node, False);
2387 return True;
2388 }
2389 }
2390
EnterLocSymbol(PSymbolEntry Neu)2391 static void EnterLocSymbol(PSymbolEntry Neu)
2392 {
2393 TEnterStruct EnterStruct;
2394 PTree TreeRoot;
2395
2396 Neu->Tree.Attribute = MomLocHandle;
2397 if (!CaseSensitive)
2398 NLS_UpString(Neu->Tree.Name);
2399 EnterStruct.MayChange = EnterStruct.DoCross = FALSE;
2400 TreeRoot = &FirstLocSymbol->Tree;
2401 EnterTree(&TreeRoot, (&Neu->Tree), SymbolAdder, &EnterStruct);
2402 FirstLocSymbol = (PSymbolEntry)TreeRoot;
2403 }
2404
EnterSymbol_Search(PForwardSymbol * Lauf,PForwardSymbol * Prev,PForwardSymbol ** RRoot,PSymbolEntry Neu,PForwardSymbol * Root,Byte ResCode,Byte * SearchErg)2405 static void EnterSymbol_Search(PForwardSymbol *Lauf, PForwardSymbol *Prev,
2406 PForwardSymbol **RRoot, PSymbolEntry Neu,
2407 PForwardSymbol *Root, Byte ResCode, Byte *SearchErg)
2408 {
2409 *Lauf = (*Root);
2410 *Prev = NULL;
2411 *RRoot = Root;
2412 while ((*Lauf) && (strcmp((*Lauf)->Name, Neu->Tree.Name)))
2413 {
2414 *Prev = (*Lauf);
2415 *Lauf = (*Lauf)->Next;
2416 }
2417 if (*Lauf)
2418 *SearchErg = ResCode;
2419 }
2420
EnterSymbol(PSymbolEntry Neu,Boolean MayChange,LongInt ResHandle)2421 static void EnterSymbol(PSymbolEntry Neu, Boolean MayChange, LongInt ResHandle)
2422 {
2423 PForwardSymbol Lauf, Prev;
2424 PForwardSymbol *RRoot;
2425 Byte SearchErg;
2426 String CombName;
2427 PSaveSection RunSect;
2428 LongInt MSect;
2429 PSymbolEntry Copy;
2430 TEnterStruct EnterStruct;
2431 PTree TreeRoot = &(FirstSymbol->Tree);
2432
2433 if (!CaseSensitive)
2434 NLS_UpString(Neu->Tree.Name);
2435
2436 SearchErg = 0;
2437 EnterStruct.MayChange = MayChange;
2438 EnterStruct.DoCross = MakeCrossList;
2439 Neu->Tree.Attribute = (ResHandle == -2) ? MomSectionHandle : ResHandle;
2440 if ((SectionStack) && (Neu->Tree.Attribute == MomSectionHandle))
2441 {
2442 EnterSymbol_Search(&Lauf, &Prev, &RRoot, Neu, &(SectionStack->LocSyms),
2443 1, &SearchErg);
2444 if (!Lauf)
2445 EnterSymbol_Search(&Lauf, &Prev, &RRoot, Neu,
2446 &(SectionStack->GlobSyms), 2, &SearchErg);
2447 if (!Lauf)
2448 EnterSymbol_Search(&Lauf, &Prev, &RRoot, Neu,
2449 &(SectionStack->ExportSyms), 3, &SearchErg);
2450 if (SearchErg == 2)
2451 Neu->Tree.Attribute = Lauf->DestSection;
2452 if (SearchErg == 3)
2453 {
2454 strmaxcpy(CombName, Neu->Tree.Name, STRINGSIZE);
2455 RunSect = SectionStack;
2456 MSect = MomSectionHandle;
2457 while ((MSect != Lauf->DestSection) && (RunSect))
2458 {
2459 strmaxprep(CombName, "_", STRINGSIZE);
2460 strmaxprep(CombName, GetSectionName(MSect), STRINGSIZE);
2461 MSect = RunSect->Handle;
2462 RunSect = RunSect->Next;
2463 }
2464 Copy = (PSymbolEntry) calloc(1, sizeof(TSymbolEntry));
2465 *Copy = (*Neu);
2466 Copy->Tree.Name = as_strdup(CombName);
2467 Copy->Tree.Attribute = Lauf->DestSection;
2468 Copy->Relocs = DupRelocs(Neu->Relocs);
2469 if (Copy->SymWert.Typ == TempString)
2470 {
2471 Copy->SymWert.Contents.String.Contents = (char*)malloc(Neu->SymWert.Contents.String.Length);
2472 memcpy(Copy->SymWert.Contents.String.Contents, Neu->SymWert.Contents.String.Contents,
2473 Copy->SymWert.Contents.String.Length = Neu->SymWert.Contents.String.Length);
2474 }
2475 EnterTree(&TreeRoot, &(Copy->Tree), SymbolAdder, &EnterStruct);
2476 }
2477 if (Lauf)
2478 {
2479 free(Lauf->Name);
2480 free(Lauf->pErrorPos);
2481 if (!Prev)
2482 *RRoot = Lauf->Next;
2483 else
2484 Prev->Next = Lauf->Next;
2485 free(Lauf);
2486 }
2487 }
2488 EnterTree(&TreeRoot, &(Neu->Tree), SymbolAdder, &EnterStruct);
2489 FirstSymbol = (PSymbolEntry)TreeRoot;
2490 }
2491
PrintSymTree(char * Name)2492 void PrintSymTree(char *Name)
2493 {
2494 fprintf(Debug, "---------------------\n");
2495 fprintf(Debug, "Enter Symbol %s\n\n", Name);
2496 PrintSymbolTree();
2497 PrintSymbolDepth();
2498 }
2499
2500 /*!------------------------------------------------------------------------
2501 * \fn ChangeSymbol(PSymbolEntry pEntry, LargeInt Value)
2502 * \brief change value of symbol in symbol table (use with caution)
2503 * \param pEntry symbol entry to modify
2504 * \param Value new (integer)value
2505 * ------------------------------------------------------------------------ */
2506
ChangeSymbol(PSymbolEntry pEntry,LargeInt Value)2507 void ChangeSymbol(PSymbolEntry pEntry, LargeInt Value)
2508 {
2509 pEntry->SymWert.Typ = TempInt;
2510 pEntry->SymWert.Contents.IWert = Value;
2511 }
2512
2513 /*!------------------------------------------------------------------------
2514 * \fn EnterIntSymbolWithFlags(const tStrComp *pName, LargeInt Wert, Byte Typ, Boolean MayChange, tSymbolFlags Flags)
2515 * \brief add integer symbol to symbol table
2516 * \param pName unexpanded name
2517 * \param Wert integer value
2518 * \param Typ symbol type
2519 * \param MayChange constant or variable?
2520 * \param Flags additional flags
2521 * \return * to newly created entry in tree
2522 * ------------------------------------------------------------------------ */
2523
CreateSymbolEntry(const tStrComp * pName,LongInt * pDestHandle)2524 PSymbolEntry CreateSymbolEntry(const tStrComp *pName, LongInt *pDestHandle)
2525 {
2526 PSymbolEntry pNeu;
2527 String ExtName;
2528
2529 if (!ExpandStrSymbol(ExtName, sizeof(ExtName), pName))
2530 return NULL;
2531 if (!GetSymSection(ExtName, pDestHandle, pName))
2532 return NULL;
2533 (void)ChkTmp(ExtName, TRUE);
2534 if (!ChkSymbName(ExtName))
2535 {
2536 WrStrErrorPos(ErrNum_InvSymName, pName);
2537 return NULL;
2538 }
2539 pNeu = (PSymbolEntry) calloc(1, sizeof(TSymbolEntry));
2540 pNeu->Tree.Name = as_strdup(ExtName);
2541 return pNeu;
2542 }
2543
EnterIntSymbolWithFlags(const tStrComp * pName,LargeInt Wert,Byte Typ,Boolean MayChange,tSymbolFlags Flags)2544 PSymbolEntry EnterIntSymbolWithFlags(const tStrComp *pName, LargeInt Wert, Byte Typ, Boolean MayChange, tSymbolFlags Flags)
2545 {
2546 LongInt DestHandle;
2547 PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle);
2548
2549 if (!pNeu)
2550 return NULL;
2551
2552 pNeu->SymWert.Typ = TempInt;
2553 pNeu->SymWert.Contents.IWert = Wert;
2554 pNeu->SymType = Typ;
2555 pNeu->Flags = Flags;
2556 pNeu->SymSize = eSymbolSizeUnknown;
2557 pNeu->RefList = NULL;
2558 pNeu->Relocs = NULL;
2559
2560 if ((MomLocHandle == -1) || (DestHandle != -2))
2561 {
2562 EnterSymbol(pNeu, MayChange, DestHandle);
2563 if (MakeDebug)
2564 PrintSymTree(pNeu->Tree.Name);
2565 }
2566 else
2567 EnterLocSymbol(pNeu);
2568 return pNeu;
2569 }
2570
2571 /*!------------------------------------------------------------------------
2572 * \fn EnterExtSymbol(const tStrComp *pName, LargeInt Wert, Byte Typ, Boolean MayChange)
2573 * \brief create extended symbol
2574 * \param pName unexpanded name
2575 * \param Wert symbol value
2576 * \param MayChange variable or constant?
2577 * ------------------------------------------------------------------------ */
2578
EnterExtSymbol(const tStrComp * pName,LargeInt Wert,Byte Typ,Boolean MayChange)2579 void EnterExtSymbol(const tStrComp *pName, LargeInt Wert, Byte Typ, Boolean MayChange)
2580 {
2581 LongInt DestHandle;
2582 PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle);
2583
2584 if (!pNeu)
2585 return;
2586
2587 pNeu = (PSymbolEntry) calloc(1, sizeof(TSymbolEntry));
2588 pNeu->SymWert.Typ = TempInt;
2589 pNeu->SymWert.Contents.IWert = Wert;
2590 pNeu->SymType = Typ;
2591 pNeu->Flags = eSymbolFlag_None;
2592 pNeu->SymSize = eSymbolSizeUnknown;
2593 pNeu->RefList = NULL;
2594 pNeu->Relocs = (PRelocEntry) malloc(sizeof(TRelocEntry));
2595 pNeu->Relocs->Next = NULL;
2596 pNeu->Relocs->Ref = as_strdup(pNeu->Tree.Name);
2597 pNeu->Relocs->Add = True;
2598
2599 if ((MomLocHandle == -1) || (DestHandle != -2))
2600 {
2601 EnterSymbol(pNeu, MayChange, DestHandle);
2602 if (MakeDebug)
2603 PrintSymTree(pNeu->Tree.Name);
2604 }
2605 else
2606 EnterLocSymbol(pNeu);
2607 }
2608
2609 /*!------------------------------------------------------------------------
2610 * \fn EnterRelSymbol(const tStrComp *pName, LargeInt Wert, Byte Typ, Boolean MayChange)
2611 * \brief enter relocatable symbol
2612 * \param pName unexpanded name
2613 * \param Wert symbol value
2614 * \param Typ symbol type
2615 * \param MayChange variable or constant?
2616 * \return * to created entry in tree
2617 * ------------------------------------------------------------------------ */
2618
EnterRelSymbol(const tStrComp * pName,LargeInt Wert,Byte Typ,Boolean MayChange)2619 PSymbolEntry EnterRelSymbol(const tStrComp *pName, LargeInt Wert, Byte Typ, Boolean MayChange)
2620 {
2621 LongInt DestHandle;
2622 PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle);
2623
2624 if (!pNeu)
2625 return NULL;
2626
2627 pNeu->SymWert.Typ = TempInt;
2628 pNeu->SymWert.Contents.IWert = Wert;
2629 pNeu->SymType = Typ;
2630 pNeu->Flags = eSymbolFlag_None;
2631 pNeu->SymSize = eSymbolSizeUnknown;
2632 pNeu->RefList = NULL;
2633 pNeu->Relocs = (PRelocEntry) malloc(sizeof(TRelocEntry));
2634 pNeu->Relocs->Next = NULL;
2635 pNeu->Relocs->Ref = as_strdup(RelName_SegStart);
2636 pNeu->Relocs->Add = True;
2637
2638 if ((MomLocHandle == -1) || (DestHandle != -2))
2639 {
2640 EnterSymbol(pNeu, MayChange, DestHandle);
2641 if (MakeDebug)
2642 PrintSymTree(pNeu->Tree.Name);
2643 }
2644 else
2645 EnterLocSymbol(pNeu);
2646
2647 return pNeu;
2648 }
2649
2650 /*!------------------------------------------------------------------------
2651 * \fn EnterFloatSymbol(const tStrComp *pName, Double Wert, Boolean MayChange)
2652 * \brief enter floating point symbol
2653 * \param pName unexpanded name
2654 * \param Wert symbol value
2655 * \param MayChange variable or constant?
2656 * ------------------------------------------------------------------------ */
2657
EnterFloatSymbol(const tStrComp * pName,Double Wert,Boolean MayChange)2658 void EnterFloatSymbol(const tStrComp *pName, Double Wert, Boolean MayChange)
2659 {
2660 LongInt DestHandle;
2661 PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle);
2662
2663 if (!pNeu)
2664 return;
2665
2666 pNeu->SymWert.Typ = TempFloat;
2667 pNeu->SymWert.Contents.FWert = Wert;
2668 pNeu->SymType = 0;
2669 pNeu->Flags = eSymbolFlag_None;
2670 pNeu->SymSize = eSymbolSizeUnknown;
2671 pNeu->RefList = NULL;
2672 pNeu->Relocs = NULL;
2673
2674 if ((MomLocHandle == -1) || (DestHandle != -2))
2675 {
2676 EnterSymbol(pNeu, MayChange, DestHandle);
2677 if (MakeDebug)
2678 PrintSymTree(pNeu->Tree.Name);
2679 }
2680 else
2681 EnterLocSymbol(pNeu);
2682 }
2683
2684 /*!------------------------------------------------------------------------
2685 * \fn EnterDynStringSymbolWithFlags(const tStrComp *pName, const tDynString *pValue, Boolean MayChange, tSymbolFlags Flags)
2686 * \brief enter string symbol
2687 * \param pName unexpanded name
2688 * \param pValue symbol value
2689 * \param MayChange variable or constant?
2690 * \param Flags special symbol flags to store
2691 * ------------------------------------------------------------------------ */
2692
EnterDynStringSymbolWithFlags(const tStrComp * pName,const tDynString * pValue,Boolean MayChange,tSymbolFlags Flags)2693 void EnterDynStringSymbolWithFlags(const tStrComp *pName, const tDynString *pValue, Boolean MayChange, tSymbolFlags Flags)
2694 {
2695 LongInt DestHandle;
2696 PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle);
2697
2698 if (!pNeu)
2699 return;
2700
2701 pNeu->SymWert.Contents.String.Contents = (char*)malloc(pValue->Length);
2702 memcpy(pNeu->SymWert.Contents.String.Contents, pValue->Contents, pValue->Length);
2703 pNeu->SymWert.Contents.String.Length = pValue->Length;
2704 pNeu->SymWert.Typ = TempString;
2705 pNeu->SymType = 0;
2706 pNeu->Flags = Flags;
2707 pNeu->SymSize = eSymbolSizeUnknown;
2708 pNeu->RefList = NULL;
2709 pNeu->Relocs = NULL;
2710
2711 if ((MomLocHandle == -1) || (DestHandle != -2))
2712 {
2713 EnterSymbol(pNeu, MayChange, DestHandle);
2714 if (MakeDebug)
2715 PrintSymTree(pNeu->Tree.Name);
2716 }
2717 else
2718 EnterLocSymbol(pNeu);
2719 }
2720
2721 /*!------------------------------------------------------------------------
2722 * \fn EnterStringSymbol(const tStrComp *pName, const char *pValue, Boolean MayChange)
2723 * \brief enter string symbol
2724 * \param pName unexpanded name
2725 * \param pValue symbol value
2726 * \param MayChange variable or constant?
2727 * ------------------------------------------------------------------------ */
2728
EnterStringSymbol(const tStrComp * pName,const char * pValue,Boolean MayChange)2729 void EnterStringSymbol(const tStrComp *pName, const char *pValue, Boolean MayChange)
2730 {
2731 tDynString DynString;
2732
2733 DynString.Length = 0;
2734 DynStringAppend(&DynString, pValue, -1);
2735 EnterDynStringSymbol(pName, &DynString, MayChange);
2736 }
2737
2738 /*!------------------------------------------------------------------------
2739 * \fn EnterRegSymbol(const struct sStrComp *pName, const tRegDescr *pDescr, tSymbolSize Size, Boolean MayChange, Boolean AddList)
2740 * \brief enter register symbol
2741 * \param pName unexpanded name
2742 * \param pDescr register's numeric value & associated dissector
2743 * \param Size register's data size
2744 * \param MayChange variable or constant?
2745 * \param AddList add value to listing?
2746 * ------------------------------------------------------------------------ */
2747
EnterRegSymbol(const struct sStrComp * pName,const tRegDescr * pDescr,tSymbolSize Size,Boolean MayChange,Boolean AddList)2748 void EnterRegSymbol(const struct sStrComp *pName, const tRegDescr *pDescr, tSymbolSize Size, Boolean MayChange, Boolean AddList)
2749 {
2750 LongInt DestHandle;
2751 PSymbolEntry pNeu = CreateSymbolEntry(pName, &DestHandle);
2752
2753 if (!pNeu)
2754 return;
2755
2756 pNeu->SymWert.Typ = TempReg;
2757 pNeu->SymWert.Contents.RegDescr = *pDescr;
2758 pNeu->SymType = 0;
2759 pNeu->Flags = eSymbolFlag_None;
2760 pNeu->SymSize = Size;
2761 pNeu->RefList = NULL;
2762 pNeu->Relocs = NULL;
2763
2764 if ((MomLocHandle == -1) || (DestHandle != -2))
2765 {
2766 EnterSymbol(pNeu, MayChange, DestHandle);
2767 if (MakeDebug)
2768 PrintSymTree(pNeu->Tree.Name);
2769 RegistersDefined = True;
2770 }
2771 else
2772 EnterLocSymbol(pNeu);
2773
2774 if (AddList)
2775 {
2776 *ListLine = '=';
2777 pDescr->Dissect(&ListLine[1], STRINGSIZE - 1, pDescr->Reg, Size);
2778 }
2779 }
2780
AddReference(PSymbolEntry Node)2781 static void AddReference(PSymbolEntry Node)
2782 {
2783 PCrossRef Lauf, Neu;
2784
2785 /* Speicher belegen */
2786
2787 Neu = (PCrossRef) malloc(sizeof(TCrossRef));
2788 Neu->LineNum = CurrLine;
2789 Neu->OccNum = 1;
2790 Neu->Next = NULL;
2791
2792 /* passende Datei heraussuchen */
2793
2794 Neu->FileNum = GetFileNum(CurrFileName);
2795
2796 /* suchen, ob Eintrag schon existiert */
2797
2798 Lauf = Node->RefList;
2799 while ((Lauf)
2800 && ((Lauf->FileNum != Neu->FileNum) || (Lauf->LineNum != Neu->LineNum)))
2801 Lauf = Lauf->Next;
2802
2803 /* schon einmal in dieser Datei in dieser Zeile aufgetaucht: nur Zaehler
2804 rauf: */
2805
2806 if (Lauf)
2807 {
2808 Lauf->OccNum++;
2809 free(Neu);
2810 }
2811
2812 /* ansonsten an Kettenende anhaengen */
2813
2814 else if (!Node->RefList) Node->RefList = Neu;
2815
2816 else
2817 {
2818 Lauf = Node->RefList;
2819 while (Lauf->Next)
2820 Lauf = Lauf->Next;
2821 Lauf->Next = Neu;
2822 }
2823 }
2824
FindNode_FNode(char * Name,TempType SearchType,LongInt Handle)2825 static PSymbolEntry FindNode_FNode(char *Name, TempType SearchType, LongInt Handle)
2826 {
2827 PSymbolEntry Lauf;
2828
2829 Lauf = (PSymbolEntry) SearchTree((PTree)FirstSymbol, Name, Handle);
2830
2831 if (Lauf)
2832 {
2833 if (Lauf->SymWert.Typ & SearchType)
2834 {
2835 if (MakeCrossList && DoRefs)
2836 AddReference(Lauf);
2837 }
2838 else
2839 Lauf = NULL;
2840 }
2841
2842 return Lauf;
2843 }
2844
FindNode_FSpec(char * Name,PForwardSymbol Root)2845 static Boolean FindNode_FSpec(char *Name, PForwardSymbol Root)
2846 {
2847 while ((Root) && (strcmp(Root->Name, Name)))
2848 Root = Root->Next;
2849 return (Root != NULL);
2850 }
2851
FindNode(const char * Name_O,TempType SearchType)2852 static PSymbolEntry FindNode(const char *Name_O, TempType SearchType)
2853 {
2854 PSaveSection Lauf;
2855 LongInt DestSection;
2856 PSymbolEntry Result = NULL;
2857 String Name;
2858
2859 strmaxcpy(Name, Name_O, STRINGSIZE);
2860 ChkTmp3(Name, FALSE);
2861
2862 /* TODO: pass StrComp */
2863 if (!GetSymSection(Name, &DestSection, NULL))
2864 return NULL;
2865
2866 if (!CaseSensitive)
2867 NLS_UpString(Name);
2868
2869 if (SectionStack)
2870 if (PassNo <= MaxSymPass)
2871 if (FindNode_FSpec(Name, SectionStack->LocSyms)) DestSection = MomSectionHandle;
2872
2873 if (DestSection == -2)
2874 {
2875 Result = FindNode_FNode(Name, SearchType, MomSectionHandle);
2876 if (Result)
2877 return Result;
2878 Lauf = SectionStack;
2879 while (Lauf)
2880 {
2881 Result = FindNode_FNode(Name, SearchType, Lauf->Handle);
2882 if (Result)
2883 break;
2884 Lauf = Lauf->Next;
2885 }
2886 }
2887 else
2888 Result = FindNode_FNode(Name, SearchType, DestSection);
2889
2890 return Result;
2891 }
2892
FindLocNode_FNode(char * Name,TempType SearchType,LongInt Handle)2893 static PSymbolEntry FindLocNode_FNode(char *Name, TempType SearchType, LongInt Handle)
2894 {
2895 PSymbolEntry Lauf;
2896
2897 Lauf = (PSymbolEntry) SearchTree((PTree)FirstLocSymbol, Name, Handle);
2898
2899 if (Lauf)
2900 {
2901 if (!(Lauf->SymWert.Typ & SearchType))
2902 Lauf = NULL;
2903 }
2904
2905 return Lauf;
2906 }
2907
FindLocNode(const char * Name_O,TempType SearchType)2908 static PSymbolEntry FindLocNode(const char *Name_O, TempType SearchType)
2909 {
2910 PLocHandle RunLocHandle;
2911 PSymbolEntry Result = NULL;
2912 String Name;
2913
2914 strmaxcpy(Name, Name_O, STRINGSIZE);
2915 ChkTmp3(Name, FALSE);
2916 if (!CaseSensitive)
2917 NLS_UpString(Name);
2918
2919 if (MomLocHandle == -1)
2920 return NULL;
2921
2922 Result = FindLocNode_FNode(Name, SearchType, MomLocHandle);
2923 if (Result)
2924 return Result;
2925
2926 RunLocHandle = FirstLocHandle;
2927 while ((RunLocHandle) && (RunLocHandle->Cont != -1))
2928 {
2929 Result = FindLocNode_FNode(Name, SearchType, RunLocHandle->Cont);
2930 if (Result)
2931 break;
2932 RunLocHandle = RunLocHandle->Next;
2933 }
2934
2935 return Result;
2936 }
2937 /**
2938 void SetSymbolType(const tStrComp *pName, Byte NTyp)
2939 {
2940 PSymbolEntry Lauf;
2941 Boolean HRef;
2942 String ExpName;
2943
2944 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
2945 return;
2946 HRef = DoRefs;
2947 DoRefs = False;
2948 Lauf = FindLocNode(ExpName, TempInt);
2949 if (!Lauf)
2950 Lauf = FindNode(ExpName, TempInt);
2951 if (Lauf)
2952 Lauf->SymType = NTyp;
2953 DoRefs = HRef;
2954 }
2955 **/
2956
LookupSymbol(const struct sStrComp * pComp,TempResult * pValue,Boolean WantRelocs,TempType ReqType)2957 void LookupSymbol(const struct sStrComp *pComp, TempResult *pValue, Boolean WantRelocs, TempType ReqType)
2958 {
2959 PSymbolEntry pEntry;
2960 String ExpName;
2961 const char *pKlPos;
2962
2963 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pComp))
2964 {
2965 pValue->Typ = TempNone;
2966 return;
2967 }
2968
2969 pKlPos = strchr(ExpName, '[');
2970 if (ChkSymbNameUpTo(ExpName, pKlPos) != pKlPos)
2971 {
2972 WrStrErrorPos(ErrNum_InvSymName, pComp);
2973 pValue->Typ = TempNone;
2974 return;
2975 }
2976
2977 pEntry = FindLocNode(ExpName, ReqType);
2978 if (!pEntry)
2979 pEntry = FindNode(ExpName, ReqType);
2980 if (pEntry)
2981 {
2982 switch (pValue->Typ = pEntry->SymWert.Typ)
2983 {
2984 case TempInt:
2985 pValue->Contents.Int = pEntry->SymWert.Contents.IWert;
2986 break;
2987 case TempFloat:
2988 pValue->Contents.Float = pEntry->SymWert.Contents.FWert;
2989 break;
2990 case TempString:
2991 pValue->Contents.Ascii.Length = 0;
2992 DynStringAppend(&pValue->Contents.Ascii, pEntry->SymWert.Contents.String.Contents, pEntry->SymWert.Contents.String.Length);
2993 break;
2994 case TempReg:
2995 pValue->Contents.RegDescr = pEntry->SymWert.Contents.RegDescr;
2996 break;
2997 default:
2998 break;
2999 }
3000 if (pValue->Typ != TempNone)
3001 {
3002 if (WantRelocs)
3003 pValue->Relocs = DupRelocs(pEntry->Relocs);
3004 pValue->Flags = pEntry->Flags;
3005 }
3006 if (pEntry->SymType != 0)
3007 pValue->AddrSpaceMask |= 1 << pEntry->SymType;
3008 if ((pEntry->SymSize != eSymbolSizeUnknown) && (pValue->DataSize == eSymbolSizeUnknown))
3009 pValue->DataSize = pEntry->SymSize;
3010 if (!pEntry->Defined)
3011 {
3012 if (Repass)
3013 pValue->Flags |= eSymbolFlag_Questionable;
3014 pValue->Flags |= eSymbolFlag_UsesForwards;
3015 }
3016 pEntry->Used = True;
3017 }
3018
3019 /* Symbol evtl. im ersten Pass unbekannt */
3020
3021 else if (PassNo <= MaxSymPass) /* !pEntry */
3022 {
3023 pValue->Typ = TempInt;
3024 pValue->Contents.Int = EProgCounter();
3025 Repass = True;
3026 if ((MsgIfRepass) && (PassNo >= PassNoForMessage))
3027 WrStrErrorPos(ErrNum_RepassUnknown, pComp);
3028 pValue->Flags |= eSymbolFlag_FirstPassUnknown;
3029 }
3030 else
3031 WrStrErrorPos(ErrNum_SymbolUndef, pComp);
3032 }
3033
3034 /*!------------------------------------------------------------------------
3035 * \fn SetSymbolOrStructElemSize(const struct sStrComp *pName, tSymbolSize Size)
3036 * \brief set (integer) data size associated with a symbol
3037 * \param pName unexpanded name of symbol
3038 * \param Size operand size to set
3039 * ------------------------------------------------------------------------ */
3040
SetSymbolOrStructElemSize(const struct sStrComp * pName,tSymbolSize Size)3041 void SetSymbolOrStructElemSize(const struct sStrComp *pName, tSymbolSize Size)
3042 {
3043 if (pInnermostNamedStruct)
3044 SetStructElemSize(pInnermostNamedStruct->StructRec, pName->Str, Size);
3045 else
3046 {
3047 PSymbolEntry pEntry;
3048 Boolean HRef;
3049 String ExpName;
3050
3051 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
3052 return;
3053 HRef = DoRefs;
3054 DoRefs = False;
3055 pEntry = FindLocNode(ExpName, TempInt);
3056 if (!pEntry)
3057 pEntry = FindNode(ExpName, TempInt);
3058 if (pEntry)
3059 pEntry->SymSize = Size;
3060 DoRefs = HRef;
3061 }
3062 }
3063
3064 /*!------------------------------------------------------------------------
3065 * \fn GetSymbolSize(const struct sStrComp *pName)
3066 * \brief get symbol's integer size
3067 * \param pName unexpanded symbol name
3068 * \return symbol size or -1 if symbol does not exist
3069 * ------------------------------------------------------------------------ */
3070
GetSymbolSize(const struct sStrComp * pName)3071 ShortInt GetSymbolSize(const struct sStrComp *pName)
3072 {
3073 PSymbolEntry pEntry;
3074 String ExpName;
3075
3076 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
3077 return -1;
3078 pEntry = FindLocNode(ExpName, TempInt);
3079 if (!pEntry)
3080 pEntry = FindNode(ExpName, TempInt);
3081 return pEntry ? pEntry->SymSize : -1;
3082 }
3083
3084 /*!------------------------------------------------------------------------
3085 * \fn IsSymbolDefined(const struct sStrComp *pName)
3086 * \brief check whether symbol nas been used so far
3087 * \param pName unexpanded symbol name
3088 * \return true if symbol exists and has been defined so far
3089 * ------------------------------------------------------------------------ */
3090
IsSymbolDefined(const struct sStrComp * pName)3091 Boolean IsSymbolDefined(const struct sStrComp *pName)
3092 {
3093 PSymbolEntry pEntry;
3094 String ExpName;
3095
3096 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
3097 return False;
3098
3099 pEntry = FindLocNode(ExpName, TempAll);
3100 if (!pEntry)
3101 pEntry = FindNode(ExpName, TempAll);
3102 return pEntry && pEntry->Defined;
3103 }
3104
3105 /*!------------------------------------------------------------------------
3106 * \fn IsSymbolUsed(const struct sStrComp *pName)
3107 * \brief check whether symbol nas been used so far
3108 * \param pName unexpanded symbol name
3109 * \return true if symbol exists and has been used
3110 * ------------------------------------------------------------------------ */
3111
IsSymbolUsed(const struct sStrComp * pName)3112 Boolean IsSymbolUsed(const struct sStrComp *pName)
3113 {
3114 PSymbolEntry pEntry;
3115 String ExpName;
3116
3117 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
3118 return False;
3119
3120 pEntry = FindLocNode(ExpName, TempAll);
3121 if (!pEntry)
3122 pEntry = FindNode(ExpName, TempAll);
3123 return pEntry && pEntry->Used;
3124 }
3125
3126 /*!------------------------------------------------------------------------
3127 * \fn IsSymbolChangeable(const struct sStrComp *pName)
3128 * \brief check whether symbol's value may be changed or is constant
3129 * \param pName unexpanded symbol name
3130 * \return true if symbol exists and is changeable
3131 * ------------------------------------------------------------------------ */
3132
IsSymbolChangeable(const struct sStrComp * pName)3133 Boolean IsSymbolChangeable(const struct sStrComp *pName)
3134 {
3135 PSymbolEntry pEntry;
3136 String ExpName;
3137
3138 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
3139 return False;
3140
3141 pEntry = FindLocNode(ExpName, TempAll);
3142 if (!pEntry)
3143 pEntry = FindNode(ExpName, TempAll);
3144 return pEntry && pEntry->Changeable;
3145 }
3146
3147 /*!------------------------------------------------------------------------
3148 * \fn GetSymbolType(const struct sStrComp *pName)
3149 * \brief retrieve type (int/float/string) of symbol
3150 * \param pName unexpanded name
3151 * \return type or -1 if non-existent
3152 * ------------------------------------------------------------------------ */
3153
GetSymbolType(const struct sStrComp * pName)3154 Integer GetSymbolType(const struct sStrComp *pName)
3155 {
3156 PSymbolEntry pEntry;
3157 String ExpName;
3158
3159 if (!ExpandStrSymbol(ExpName, sizeof(ExpName), pName))
3160 return -1;
3161
3162 pEntry = FindLocNode(ExpName, TempAll);
3163 if (!pEntry)
3164 pEntry = FindNode(ExpName, TempAll);
3165
3166 if (!pEntry)
3167 return -1;
3168 else if (pEntry->SymType == TempReg)
3169 return 0x80;
3170 else
3171 return pEntry->SymType;
3172 }
3173
ConvertSymbolVal(const PSymbolEntry pInp,TempResult * Outp)3174 static void ConvertSymbolVal(const PSymbolEntry pInp, TempResult *Outp)
3175 {
3176 switch (Outp->Typ = pInp->SymWert.Typ)
3177 {
3178 case TempInt:
3179 Outp->Contents.Int = pInp->SymWert.Contents.IWert;
3180 break;
3181 case TempFloat:
3182 Outp->Contents.Float = pInp->SymWert.Contents.FWert;
3183 break;
3184 case TempString:
3185 Outp->Contents.Ascii.Length = 0;
3186 DynStringAppend(&Outp->Contents.Ascii, pInp->SymWert.Contents.String.Contents, pInp->SymWert.Contents.String.Length);
3187 break;
3188 case TempReg:
3189 Outp->Contents.RegDescr = pInp->SymWert.Contents.RegDescr;
3190 break;
3191 default:
3192 break;
3193 }
3194 Outp->Flags = pInp->Flags;
3195 Outp->DataSize = pInp->SymSize;
3196 }
3197
3198 typedef struct
3199 {
3200 int Width, cwidth;
3201 LongInt Sum, USum;
3202 String Zeilenrest;
3203 int ZeilenrestLen,
3204 ZeilenrestVisibleLen;
3205 } TListContext;
3206
PrintSymbolList_AddOut(char * s,TListContext * pContext)3207 static void PrintSymbolList_AddOut(char *s, TListContext *pContext)
3208 {
3209 int AddVisibleLen = visible_strlen(s),
3210 AddLen = strlen(s);
3211
3212 if (AddVisibleLen + pContext->ZeilenrestVisibleLen > pContext->Width)
3213 {
3214 pContext->Zeilenrest[pContext->ZeilenrestLen - 1] = '\0';
3215 WrLstLine(pContext->Zeilenrest);
3216 strmaxcpy(pContext->Zeilenrest, s, STRINGSIZE);
3217 pContext->ZeilenrestLen = AddLen;
3218 pContext->ZeilenrestVisibleLen = AddVisibleLen;
3219 }
3220 else
3221 {
3222 strmaxcat(pContext->Zeilenrest, s, STRINGSIZE);
3223 pContext->ZeilenrestLen += AddLen;
3224 pContext->ZeilenrestVisibleLen += AddVisibleLen;
3225 }
3226 }
3227
PrintSymbolList_PNode(PTree Tree,void * pData)3228 static void PrintSymbolList_PNode(PTree Tree, void *pData)
3229 {
3230 PSymbolEntry Node = (PSymbolEntry) Tree;
3231
3232 if (Node->SymWert.Typ != TempReg)
3233 {
3234 TListContext *pContext = (TListContext*) pData;
3235 String s1, sh;
3236 int l1, nBlanks;
3237 TempResult t;
3238
3239 ConvertSymbolVal(Node, &t);
3240 if ((t.Typ == TempInt) && DissectBit && (Node->SymType == SegBData))
3241 DissectBit(s1, sizeof(s1), t.Contents.Int);
3242 else
3243 StrSym(&t, False, s1, sizeof(s1), ListRadixBase);
3244
3245 as_snprintf(sh, STRINGSIZE, "%c%s : ", Node->Used ? ' ' : '*', Tree->Name);
3246 if (Tree->Attribute != -1)
3247 as_snprcatf(sh, STRINGSIZE, " [%s]", GetSectionName(Tree->Attribute));
3248 l1 = (strlen(s1) + visible_strlen(sh) + 4);
3249 for (nBlanks = pContext->cwidth - 1 - l1; nBlanks < 0; nBlanks += pContext->cwidth);
3250 as_snprcatf(sh, STRINGSIZE, "%s%s %c | ", Blanks(nBlanks), s1, SegShorts[Node->SymType]);
3251 PrintSymbolList_AddOut(sh, pContext);
3252 pContext->Sum++;
3253 if (!Node->Used)
3254 pContext->USum++;
3255 }
3256 }
3257
PrintSymbolList(void)3258 void PrintSymbolList(void)
3259 {
3260 int ActPageWidth;
3261 TListContext Context;
3262
3263 Context.Width = (PageWidth == 0) ? 80 : PageWidth;
3264 NewPage(ChapDepth, True);
3265 WrLstLine(getmessage(Num_ListSymListHead1));
3266 WrLstLine(getmessage(Num_ListSymListHead2));
3267 WrLstLine("");
3268
3269 Context.Zeilenrest[0] = '\0';
3270 Context.ZeilenrestLen =
3271 Context.ZeilenrestVisibleLen = 0;
3272 Context.Sum = Context.USum = 0;
3273 ActPageWidth = (PageWidth == 0) ? 80 : PageWidth;
3274 Context.cwidth = ActPageWidth >> 1;
3275 IterTree((PTree)FirstSymbol, PrintSymbolList_PNode, &Context);
3276 if (Context.Zeilenrest[0] != '\0')
3277 {
3278 Context.Zeilenrest[strlen(Context.Zeilenrest) - 1] = '\0';
3279 WrLstLine(Context.Zeilenrest);
3280 }
3281 WrLstLine("");
3282 as_snprintf(Context.Zeilenrest, sizeof(Context.Zeilenrest), "%7lu%s",
3283 (unsigned long)Context.Sum,
3284 getmessage((Context.Sum == 1) ? Num_ListSymSumMsg : Num_ListSymSumsMsg));
3285 WrLstLine(Context.Zeilenrest);
3286 as_snprintf(Context.Zeilenrest, sizeof(Context.Zeilenrest), "%7lu%s",
3287 (unsigned long)Context.USum,
3288 getmessage((Context.USum == 1) ? Num_ListUSymSumMsg : Num_ListUSymSumsMsg));
3289 WrLstLine(Context.Zeilenrest);
3290 WrLstLine("");
3291 }
3292
3293 typedef struct
3294 {
3295 FILE *f;
3296 Boolean HWritten;
3297 int Space;
3298 } TDebContext;
3299
PrintDebSymbols_PNode(PTree Tree,void * pData)3300 static void PrintDebSymbols_PNode(PTree Tree, void *pData)
3301 {
3302 PSymbolEntry Node = (PSymbolEntry) Tree;
3303 TDebContext *DebContext = (TDebContext*) pData;
3304 int l1;
3305 TempResult t;
3306 String s;
3307
3308 if (Node->SymType != DebContext->Space)
3309 return;
3310
3311 if (!DebContext->HWritten)
3312 {
3313 fprintf(DebContext->f, "\n"); ChkIO(ErrNum_FileWriteError);
3314 fprintf(DebContext->f, "Symbols in Segment %s\n", SegNames[DebContext->Space]); ChkIO(ErrNum_FileWriteError);
3315 DebContext->HWritten = True;
3316 }
3317
3318 fprintf(DebContext->f, "%s", Node->Tree.Name); ChkIO(ErrNum_FileWriteError);
3319 l1 = strlen(Node->Tree.Name);
3320 if (Node->Tree.Attribute != -1)
3321 {
3322 as_snprintf(s, sizeof(s), "[%d]", (int)Node->Tree.Attribute);
3323 fprintf(DebContext->f, "%s", s); ChkIO(ErrNum_FileWriteError);
3324 l1 += strlen(s);
3325 }
3326 fprintf(DebContext->f, "%s ", Blanks(37 - l1)); ChkIO(ErrNum_FileWriteError);
3327 switch (Node->SymWert.Typ)
3328 {
3329 case TempInt:
3330 fprintf(DebContext->f, "Int ");
3331 break;
3332 case TempFloat:
3333 fprintf(DebContext->f, "Float ");
3334 break;
3335 case TempString:
3336 fprintf(DebContext->f, "String ");
3337 break;
3338 default:
3339 break;
3340 }
3341 ChkIO(ErrNum_FileWriteError);
3342 if (Node->SymWert.Typ == TempString)
3343 {
3344 errno = 0;
3345 l1 = fstrlenprint(DebContext->f, Node->SymWert.Contents.String.Contents, Node->SymWert.Contents.String.Length);
3346 ChkIO(ErrNum_FileWriteError);
3347 }
3348 else
3349 {
3350 ConvertSymbolVal(Node, &t);
3351 StrSym(&t, False, s, sizeof(s), 16);
3352 l1 = strlen(s);
3353 fprintf(DebContext->f, "%s", s); ChkIO(ErrNum_FileWriteError);
3354 }
3355 fprintf(DebContext->f, "%s %-3d %d %d\n", Blanks(25-l1), Node->SymSize, (int)Node->Used, (int)Node->Changeable);
3356 ChkIO(ErrNum_FileWriteError);
3357 }
3358
PrintDebSymbols(FILE * f)3359 void PrintDebSymbols(FILE *f)
3360 {
3361 TDebContext DebContext;
3362
3363 DebContext.f = f;
3364 for (DebContext.Space = 0; DebContext.Space < PCMax; DebContext.Space++)
3365 {
3366 DebContext.HWritten = False;
3367 IterTree((PTree)FirstSymbol, PrintDebSymbols_PNode, &DebContext);
3368 }
3369 }
3370
3371 typedef struct
3372 {
3373 FILE *f;
3374 LongInt Handle;
3375 } TNoISymContext;
3376
PrNoISection(PTree Tree,void * pData)3377 static void PrNoISection(PTree Tree, void *pData)
3378 {
3379 PSymbolEntry Node = (PSymbolEntry)Tree;
3380 TNoISymContext *pContext = (TNoISymContext*) pData;
3381
3382 if (((1 << Node->SymType) & NoICEMask) && (Node->Tree.Attribute == pContext->Handle) && (Node->SymWert.Typ == TempInt))
3383 {
3384 errno = 0; fprintf(pContext->f, "DEFINE %s 0x", Node->Tree.Name); ChkIO(ErrNum_FileWriteError);
3385 errno = 0; fprintf(pContext->f, LargeHIntFormat, Node->SymWert.Contents.IWert); ChkIO(ErrNum_FileWriteError);
3386 errno = 0; fprintf(pContext->f, "\n"); ChkIO(ErrNum_FileWriteError);
3387 }
3388 }
3389
PrintNoISymbols(FILE * f)3390 void PrintNoISymbols(FILE *f)
3391 {
3392 PCToken CurrSection;
3393 TNoISymContext Context;
3394
3395 Context.f = f;
3396 Context.Handle = -1;
3397 IterTree((PTree)FirstSymbol, PrNoISection, &Context);
3398 Context.Handle++;
3399 for (CurrSection = FirstSection; CurrSection; CurrSection = CurrSection->Next)
3400 if (ChunkSum(&CurrSection->Usage)>0)
3401 {
3402 fprintf(f, "FUNCTION %s ", CurrSection->Name); ChkIO(ErrNum_FileWriteError);
3403 fprintf(f, LargeIntFormat, ChunkMin(&CurrSection->Usage)); ChkIO(ErrNum_FileWriteError);
3404 fprintf(f, "\n"); ChkIO(ErrNum_FileWriteError);
3405 IterTree((PTree)FirstSymbol, PrNoISection, &Context);
3406 Context.Handle++;
3407 fprintf(f, "}FUNC "); ChkIO(ErrNum_FileWriteError);
3408 fprintf(f, LargeIntFormat, ChunkMax(&CurrSection->Usage)); ChkIO(ErrNum_FileWriteError);
3409 fprintf(f, "\n"); ChkIO(ErrNum_FileWriteError);
3410 }
3411 }
3412
PrintSymbolTree(void)3413 void PrintSymbolTree(void)
3414 {
3415 DumpTree((PTree)FirstSymbol);
3416 }
3417
ClearSymbolList_ClearNode(PTree Node,void * pData)3418 static void ClearSymbolList_ClearNode(PTree Node, void *pData)
3419 {
3420 PSymbolEntry SymbolEntry = (PSymbolEntry) Node;
3421 UNUSED(pData);
3422
3423 FreeSymbolEntry(&SymbolEntry, FALSE);
3424 }
3425
ClearSymbolList(void)3426 void ClearSymbolList(void)
3427 {
3428 PTree TreeRoot;
3429
3430 TreeRoot = &(FirstSymbol->Tree);
3431 FirstSymbol = NULL;
3432 DestroyTree(&TreeRoot, ClearSymbolList_ClearNode, NULL);
3433 TreeRoot = &(FirstLocSymbol->Tree);
3434 FirstLocSymbol = NULL;
3435 DestroyTree(&TreeRoot, ClearSymbolList_ClearNode, NULL);
3436 }
3437
3438 /*-------------------------------------------------------------------------*/
3439 /* Stack-Verwaltung */
3440
PushSymbol(const tStrComp * pSymName,const tStrComp * pStackName)3441 Boolean PushSymbol(const tStrComp *pSymName, const tStrComp *pStackName)
3442 {
3443 PSymbolEntry pSrc;
3444 PSymbolStack LStack, NStack, PStack;
3445 PSymbolStackEntry Elem;
3446 String ExpSymName, ExpStackName;
3447
3448 if (!ExpandStrSymbol(ExpSymName, sizeof(ExpSymName), pSymName))
3449 return False;
3450
3451 pSrc = FindNode(ExpSymName, TempAll);
3452 if (!pSrc)
3453 {
3454 WrStrErrorPos(ErrNum_SymbolUndef, pSymName);
3455 return False;
3456 }
3457
3458 if (*pStackName->Str)
3459 {
3460 if (!ExpandStrSymbol(ExpStackName, sizeof(ExpStackName), pStackName))
3461 return False;
3462 }
3463 else
3464 strmaxcpy(ExpStackName, DefStackName, STRINGSIZE);
3465 if (!ChkSymbName(ExpStackName))
3466 {
3467 WrStrErrorPos(ErrNum_InvSymName, pStackName);
3468 return False;
3469 }
3470
3471 LStack = FirstStack;
3472 PStack = NULL;
3473 while ((LStack) && (strcmp(LStack->Name, ExpStackName) < 0))
3474 {
3475 PStack = LStack;
3476 LStack = LStack->Next;
3477 }
3478
3479 if ((!LStack) || (strcmp(LStack->Name, ExpStackName) > 0))
3480 {
3481 NStack = (PSymbolStack) malloc(sizeof(TSymbolStack));
3482 NStack->Name = as_strdup(ExpStackName);
3483 NStack->Contents = NULL;
3484 NStack->Next = LStack;
3485 if (!PStack)
3486 FirstStack = NStack;
3487 else
3488 PStack->Next = NStack;
3489 LStack = NStack;
3490 }
3491
3492 Elem = (PSymbolStackEntry) malloc(sizeof(TSymbolStackEntry));
3493 Elem->Next = LStack->Contents;
3494 Elem->Contents = pSrc->SymWert;
3495 LStack->Contents = Elem;
3496
3497 return True;
3498 }
3499
PopSymbol(const tStrComp * pSymName,const tStrComp * pStackName)3500 Boolean PopSymbol(const tStrComp *pSymName, const tStrComp *pStackName)
3501 {
3502 PSymbolEntry pDest;
3503 PSymbolStack LStack, PStack;
3504 PSymbolStackEntry Elem;
3505 String ExpSymName, ExpStackName;
3506
3507 if (!ExpandStrSymbol(ExpSymName, sizeof(ExpSymName), pSymName))
3508 return False;
3509
3510 pDest = FindNode(ExpSymName, TempAll);
3511 if (!pDest)
3512 {
3513 WrStrErrorPos(ErrNum_SymbolUndef, pSymName);
3514 return False;
3515 }
3516
3517 if (*pStackName->Str)
3518 {
3519 if (!ExpandStrSymbol(ExpStackName, sizeof(ExpStackName), pStackName))
3520 return False;
3521 }
3522 else
3523 strmaxcpy(ExpStackName, DefStackName, STRINGSIZE);
3524 if (!ChkSymbName(ExpStackName))
3525 {
3526 WrStrErrorPos(ErrNum_InvSymName, pStackName);
3527 return False;
3528 }
3529
3530 LStack = FirstStack;
3531 PStack = NULL;
3532 while ((LStack) && (strcmp(LStack->Name, ExpStackName) < 0))
3533 {
3534 PStack = LStack;
3535 LStack = LStack->Next;
3536 }
3537
3538 if ((!LStack) || (strcmp(LStack->Name, ExpStackName) > 0))
3539 {
3540 WrStrErrorPos(ErrNum_StackEmpty, pStackName);
3541 return False;
3542 }
3543
3544 Elem = LStack->Contents;
3545 pDest->SymWert = Elem->Contents;
3546 LStack->Contents = Elem->Next;
3547 if (!LStack->Contents)
3548 {
3549 if (!PStack)
3550 FirstStack = LStack->Next;
3551 else
3552 PStack->Next = LStack->Next;
3553 free(LStack->Name);
3554 free(LStack);
3555 }
3556 free(Elem);
3557
3558 return True;
3559 }
3560
ClearStacks(void)3561 void ClearStacks(void)
3562 {
3563 PSymbolStack Act;
3564 PSymbolStackEntry Elem;
3565 int z;
3566 String s;
3567
3568 while (FirstStack)
3569 {
3570 z = 0;
3571 Act = FirstStack;
3572 while (Act->Contents)
3573 {
3574 Elem = Act->Contents;
3575 Act->Contents = Elem->Next;
3576 free(Elem);
3577 z++;
3578 }
3579 as_snprintf(s, sizeof(s), "%s(%d)", Act->Name, z);
3580 WrXError(ErrNum_StackNotEmpty, s);
3581 free(Act->Name);
3582 FirstStack = Act->Next;
3583 free(Act);
3584 }
3585 }
3586
3587 /*-------------------------------------------------------------------------*/
3588 /* Funktionsverwaltung */
3589
EnterFunction(const tStrComp * pComp,char * FDefinition,Byte NewCnt)3590 void EnterFunction(const tStrComp *pComp, char *FDefinition, Byte NewCnt)
3591 {
3592 PFunction Neu;
3593 String FName_N;
3594 const char *pFName;
3595
3596 if (!CaseSensitive)
3597 {
3598 strmaxcpy(FName_N, pComp->Str, STRINGSIZE);
3599 NLS_UpString(FName_N);
3600 pFName = FName_N;
3601 }
3602 else
3603 pFName = pComp->Str;
3604
3605 if (!ChkSymbName(pFName))
3606 {
3607 WrStrErrorPos(ErrNum_InvSymName, pComp);
3608 return;
3609 }
3610
3611 if (FindFunction(pFName))
3612 {
3613 if (PassNo == 1)
3614 WrStrErrorPos(ErrNum_DoubleDef, pComp);
3615 return;
3616 }
3617
3618 Neu = (PFunction) malloc(sizeof(TFunction));
3619 Neu->Next = FirstFunction;
3620 Neu->ArguCnt = NewCnt;
3621 Neu->Name = as_strdup(pFName);
3622 Neu->Definition = as_strdup(FDefinition);
3623 FirstFunction = Neu;
3624 }
3625
FindFunction(const char * Name)3626 PFunction FindFunction(const char *Name)
3627 {
3628 PFunction Lauf = FirstFunction;
3629 String Name_N;
3630
3631 if (!CaseSensitive)
3632 {
3633 strmaxcpy(Name_N, Name, STRINGSIZE);
3634 NLS_UpString(Name_N);
3635 Name = Name_N;
3636 }
3637
3638 while ((Lauf) && (strcmp(Lauf->Name, Name)))
3639 Lauf = Lauf->Next;
3640 return Lauf;
3641 }
3642
PrintFunctionList(void)3643 void PrintFunctionList(void)
3644 {
3645 PFunction Lauf;
3646 String OneS;
3647 Boolean cnt;
3648
3649 if (!FirstFunction)
3650 return;
3651
3652 NewPage(ChapDepth, True);
3653 WrLstLine(getmessage(Num_ListFuncListHead1));
3654 WrLstLine(getmessage(Num_ListFuncListHead2));
3655 WrLstLine("");
3656
3657 OneS[0] = '\0';
3658 Lauf = FirstFunction;
3659 cnt = False;
3660 while (Lauf)
3661 {
3662 strmaxcat(OneS, Lauf->Name, STRINGSIZE);
3663 if (strlen(Lauf->Name) < 37)
3664 strmaxcat(OneS, Blanks(37-strlen(Lauf->Name)), STRINGSIZE);
3665 if (!cnt) strmaxcat(OneS, " | ", STRINGSIZE);
3666 else
3667 {
3668 WrLstLine(OneS);
3669 OneS[0] = '\0';
3670 }
3671 cnt = !cnt;
3672 Lauf = Lauf->Next;
3673 }
3674 if (cnt)
3675 {
3676 OneS[strlen(OneS)-1] = '\0';
3677 WrLstLine(OneS);
3678 }
3679 WrLstLine("");
3680 }
3681
ClearFunctionList(void)3682 void ClearFunctionList(void)
3683 {
3684 PFunction Lauf;
3685
3686 while (FirstFunction)
3687 {
3688 Lauf = FirstFunction->Next;
3689 free(FirstFunction->Name);
3690 free(FirstFunction->Definition);
3691 free(FirstFunction);
3692 FirstFunction = Lauf;
3693 }
3694 }
3695
3696 /*-------------------------------------------------------------------------*/
3697
ResetSymbolDefines_ResetNode(PTree Node,void * pData)3698 static void ResetSymbolDefines_ResetNode(PTree Node, void *pData)
3699 {
3700 PSymbolEntry SymbolEntry = (PSymbolEntry) Node;
3701 UNUSED(pData);
3702
3703 SymbolEntry->Defined = False;
3704 SymbolEntry->Used = False;
3705 }
3706
ResetSymbolDefines(void)3707 void ResetSymbolDefines(void)
3708 {
3709 IterTree(&(FirstSymbol->Tree), ResetSymbolDefines_ResetNode, NULL);
3710 IterTree(&(FirstLocSymbol->Tree), ResetSymbolDefines_ResetNode, NULL);
3711 }
3712
SetFlag(Boolean * Flag,const char * Name,Boolean Wert)3713 void SetFlag(Boolean *Flag, const char *Name, Boolean Wert)
3714 {
3715 tStrComp TmpComp;
3716
3717 *Flag = Wert;
3718 StrCompMkTemp(&TmpComp, (char*)Name);
3719 EnterIntSymbol(&TmpComp, *Flag ? 1 : 0, 0, True);
3720 }
3721
AddDefSymbol(char * Name,TempResult * Value)3722 void AddDefSymbol(char *Name, TempResult *Value)
3723 {
3724 PDefSymbol Neu;
3725
3726 Neu = FirstDefSymbol;
3727 while (Neu)
3728 {
3729 if (!strcmp(Neu->SymName, Name))
3730 return;
3731 Neu = Neu->Next;
3732 }
3733
3734 Neu = (PDefSymbol) malloc(sizeof(TDefSymbol));
3735 Neu->Next = FirstDefSymbol;
3736 Neu->SymName = as_strdup(Name);
3737 Neu->Wert = (*Value);
3738 FirstDefSymbol = Neu;
3739 }
3740
RemoveDefSymbol(char * Name)3741 void RemoveDefSymbol(char *Name)
3742 {
3743 PDefSymbol Save, Lauf;
3744
3745 if (!FirstDefSymbol)
3746 return;
3747
3748 if (!strcmp(FirstDefSymbol->SymName, Name))
3749 {
3750 Save = FirstDefSymbol;
3751 FirstDefSymbol = FirstDefSymbol->Next;
3752 }
3753 else
3754 {
3755 Lauf = FirstDefSymbol;
3756 while ((Lauf->Next) && (strcmp(Lauf->Next->SymName, Name)))
3757 Lauf = Lauf->Next;
3758 if (!Lauf->Next)
3759 return;
3760 Save = Lauf->Next;
3761 Lauf->Next = Lauf->Next->Next;
3762 }
3763 free(Save->SymName);
3764 free(Save);
3765 }
3766
CopyDefSymbols(void)3767 void CopyDefSymbols(void)
3768 {
3769 PDefSymbol Lauf;
3770 tStrComp TmpComp;
3771
3772 Lauf = FirstDefSymbol;
3773 while (Lauf)
3774 {
3775 StrCompMkTemp(&TmpComp, Lauf->SymName);
3776 switch (Lauf->Wert.Typ)
3777 {
3778 case TempInt:
3779 EnterIntSymbol(&TmpComp, Lauf->Wert.Contents.Int, 0, True);
3780 break;
3781 case TempFloat:
3782 EnterFloatSymbol(&TmpComp, Lauf->Wert.Contents.Float, True);
3783 break;
3784 case TempString:
3785 EnterDynStringSymbol(&TmpComp, &Lauf->Wert.Contents.Ascii, True);
3786 break;
3787 default:
3788 break;
3789 }
3790 Lauf = Lauf->Next;
3791 }
3792 }
3793
FindDefSymbol(const char * pName)3794 const TempResult *FindDefSymbol(const char *pName)
3795 {
3796 PDefSymbol pRun;
3797
3798 for (pRun = FirstDefSymbol; pRun; pRun = pRun->Next)
3799 if (!strcmp(pName, pRun->SymName))
3800 return &pRun->Wert;
3801 return NULL;
3802 }
3803
PrintSymbolDepth(void)3804 void PrintSymbolDepth(void)
3805 {
3806 LongInt TreeMin, TreeMax;
3807
3808 GetTreeDepth(&(FirstSymbol->Tree), &TreeMin, &TreeMax);
3809 fprintf(Debug, " MinTree %ld\n", (long)TreeMin);
3810 fprintf(Debug, " MaxTree %ld\n", (long)TreeMax);
3811 }
3812
GetSectionHandle(char * SName_O,Boolean AddEmpt,LongInt Parent)3813 LongInt GetSectionHandle(char *SName_O, Boolean AddEmpt, LongInt Parent)
3814 {
3815 PCToken Lauf, Prev;
3816 LongInt z;
3817 String SName;
3818
3819 strmaxcpy(SName, SName_O, STRINGSIZE);
3820 if (!CaseSensitive)
3821 NLS_UpString(SName);
3822
3823 Lauf = FirstSection;
3824 Prev = NULL;
3825 z = 0;
3826 while ((Lauf) && ((strcmp(Lauf->Name, SName)) || (Lauf->Parent != Parent)))
3827 {
3828 z++;
3829 Prev = Lauf;
3830 Lauf = Lauf->Next;
3831 }
3832
3833 if (!Lauf)
3834 {
3835 if (AddEmpt)
3836 {
3837 Lauf = (PCToken) malloc(sizeof(TCToken));
3838 Lauf->Parent = MomSectionHandle;
3839 Lauf->Name = as_strdup(SName);
3840 Lauf->Next = NULL;
3841 InitChunk(&(Lauf->Usage));
3842 if (!Prev)
3843 FirstSection = Lauf;
3844 else
3845 Prev->Next = Lauf;
3846 }
3847 else
3848 z = -2;
3849 }
3850 return z;
3851 }
3852
GetSectionName(LongInt Handle)3853 const char *GetSectionName(LongInt Handle)
3854 {
3855 PCToken Lauf = FirstSection;
3856 static const char *Dummy = "";
3857
3858 if (Handle == -1)
3859 return Dummy;
3860 while ((Handle > 0) && (Lauf))
3861 {
3862 Lauf = Lauf->Next;
3863 Handle--;
3864 }
3865 return Lauf ? Lauf->Name : Dummy;
3866 }
3867
SetMomSection(LongInt Handle)3868 void SetMomSection(LongInt Handle)
3869 {
3870 LongInt z;
3871
3872 MomSectionHandle = Handle;
3873 if (Handle < 0)
3874 MomSection = NULL;
3875 else
3876 {
3877 MomSection = FirstSection;
3878 for (z = 1; z <= Handle; z++)
3879 if (MomSection)
3880 MomSection = MomSection->Next;
3881 }
3882 }
3883
AddSectionUsage(LongInt Start,LongInt Length)3884 void AddSectionUsage(LongInt Start, LongInt Length)
3885 {
3886 if ((ActPC != SegCode) || (!MomSection))
3887 return;
3888 AddChunk(&(MomSection->Usage), Start, Length, False);
3889 }
3890
ClearSectionUsage(void)3891 void ClearSectionUsage(void)
3892 {
3893 PCToken Tmp;
3894
3895 for (Tmp = FirstSection; Tmp; Tmp = Tmp->Next)
3896 ClearChunk(&(Tmp->Usage));
3897 }
3898
PrintSectionList_PSection(LongInt Handle,int Indent)3899 static void PrintSectionList_PSection(LongInt Handle, int Indent)
3900 {
3901 PCToken Lauf;
3902 LongInt Cnt;
3903 String h;
3904
3905 ChkStack();
3906 if (Handle != -1)
3907 {
3908 strmaxcpy(h, Blanks(Indent << 1), STRINGSIZE);
3909 strmaxcat(h, GetSectionName(Handle), STRINGSIZE);
3910 WrLstLine(h);
3911 }
3912 Lauf = FirstSection;
3913 Cnt = 0;
3914 while (Lauf)
3915 {
3916 if (Lauf->Parent == Handle)
3917 PrintSectionList_PSection(Cnt, Indent + 1);
3918 Lauf = Lauf->Next;
3919 Cnt++;
3920 }
3921 }
3922
PrintSectionList(void)3923 void PrintSectionList(void)
3924 {
3925 if (!FirstSection)
3926 return;
3927
3928 NewPage(ChapDepth, True);
3929 WrLstLine(getmessage(Num_ListSectionListHead1));
3930 WrLstLine(getmessage(Num_ListSectionListHead2));
3931 WrLstLine("");
3932 PrintSectionList_PSection(-1, 0);
3933 }
3934
PrintDebSections(FILE * f)3935 void PrintDebSections(FILE *f)
3936 {
3937 PCToken Lauf;
3938 LongInt Cnt, z, l, s;
3939 char Str[30];
3940
3941 Lauf = FirstSection; Cnt = 0;
3942 while (Lauf)
3943 {
3944 fputs("\nInfo for Section ", f); ChkIO(ErrNum_FileWriteError);
3945 fprintf(f, LongIntFormat, Cnt); ChkIO(ErrNum_FileWriteError);
3946 fputc(' ', f); ChkIO(ErrNum_FileWriteError);
3947 fputs(GetSectionName(Cnt), f); ChkIO(ErrNum_FileWriteError);
3948 fputc(' ', f); ChkIO(ErrNum_FileWriteError);
3949 fprintf(f, LongIntFormat, Lauf->Parent); ChkIO(ErrNum_FileWriteError);
3950 fputc('\n', f); ChkIO(ErrNum_FileWriteError);
3951 for (z = 0; z < Lauf->Usage.RealLen; z++)
3952 {
3953 l = Lauf->Usage.Chunks[z].Length;
3954 s = Lauf->Usage.Chunks[z].Start;
3955 HexString(Str, sizeof(Str), s, 0);
3956 fputs(Str, f);
3957 ChkIO(ErrNum_FileWriteError);
3958 if (l == 1)
3959 fprintf(f, "\n");
3960 else
3961 {
3962 HexString(Str, sizeof(Str), s + l - 1, 0);
3963 fprintf(f, "-%s\n", Str);
3964 }
3965 ChkIO(ErrNum_FileWriteError);
3966 }
3967 Lauf = Lauf->Next;
3968 Cnt++;
3969 }
3970 }
3971
ClearSectionList(void)3972 void ClearSectionList(void)
3973 {
3974 PCToken Tmp;
3975
3976 while (FirstSection)
3977 {
3978 Tmp = FirstSection;
3979 free(Tmp->Name);
3980 ClearChunk(&(Tmp->Usage));
3981 FirstSection = Tmp->Next; free(Tmp);
3982 }
3983 }
3984
3985 /*---------------------------------------------------------------------------------*/
3986
PrintCrossList_PNode(PTree Node,void * pData)3987 static void PrintCrossList_PNode(PTree Node, void *pData)
3988 {
3989 int FileZ;
3990 PCrossRef Lauf;
3991 String LinePart, LineAcc;
3992 String h, ValStr;
3993 char LineStr[30];
3994 TempResult t;
3995 PSymbolEntry SymbolEntry = (PSymbolEntry) Node;
3996 UNUSED(pData);
3997
3998 if (!SymbolEntry->RefList)
3999 return;
4000
4001 ConvertSymbolVal(SymbolEntry, &t);
4002 StrSym(&t, False, ValStr, sizeof(ValStr), ListRadixBase);
4003 as_snprintf(LineStr, sizeof(LineStr), LongIntFormat, SymbolEntry->LineNum);
4004
4005 as_snprintf(h, sizeof(h), "%s%s",
4006 getmessage(Num_ListCrossSymName), Node->Name);
4007 if (Node->Attribute != -1)
4008 as_snprcatf(h, sizeof(h), "[%s]", GetSectionName(Node->Attribute));
4009 as_snprcatf(h, sizeof(h), " (=%s, %s:%s):",
4010 ValStr, GetFileName(SymbolEntry->FileNum), LineStr);
4011
4012
4013 WrLstLine(h);
4014
4015 for (FileZ = 0; FileZ < GetFileCount(); FileZ++)
4016 {
4017 Lauf = SymbolEntry->RefList;
4018
4019 while ((Lauf) && (Lauf->FileNum != FileZ))
4020 Lauf = Lauf->Next;
4021
4022 if (Lauf)
4023 {
4024 strcpy(h, " ");
4025 strmaxcat(h, getmessage(Num_ListCrossFileName), STRINGSIZE);
4026 strmaxcat(h, GetFileName(FileZ), STRINGSIZE);
4027 strmaxcat(h, " :", STRINGSIZE);
4028 WrLstLine(h);
4029 strcpy(LineAcc, " ");
4030 while (Lauf)
4031 {
4032 as_snprintf(LinePart, sizeof(LinePart), "%5ld", (long)Lauf->LineNum);
4033 strmaxcat(LineAcc, LinePart, STRINGSIZE);
4034 if (Lauf->OccNum != 1)
4035 {
4036 as_snprintf(LinePart, sizeof(LinePart), "(%2ld)", (long)Lauf->OccNum);
4037 strmaxcat(LineAcc, LinePart, STRINGSIZE);
4038 }
4039 else strmaxcat(LineAcc, " ", STRINGSIZE);
4040 if (strlen(LineAcc) >= 72)
4041 {
4042 WrLstLine(LineAcc);
4043 strcpy(LineAcc, " ");
4044 }
4045 Lauf = Lauf->Next;
4046 }
4047 if (strcmp(LineAcc, " "))
4048 WrLstLine(LineAcc);
4049 }
4050 }
4051 WrLstLine("");
4052 }
4053
PrintCrossList(void)4054 void PrintCrossList(void)
4055 {
4056 WrLstLine("");
4057 WrLstLine(getmessage(Num_ListCrossListHead1));
4058 WrLstLine(getmessage(Num_ListCrossListHead2));
4059 WrLstLine("");
4060 IterTree(&(FirstSymbol->Tree), PrintCrossList_PNode, NULL);
4061 WrLstLine("");
4062 }
4063
ClearCrossList_CNode(PTree Tree,void * pData)4064 static void ClearCrossList_CNode(PTree Tree, void *pData)
4065 {
4066 PCrossRef Lauf;
4067 PSymbolEntry SymbolEntry = (PSymbolEntry) Tree;
4068 UNUSED(pData);
4069
4070 while (SymbolEntry->RefList)
4071 {
4072 Lauf = SymbolEntry->RefList->Next;
4073 free(SymbolEntry->RefList);
4074 SymbolEntry->RefList = Lauf;
4075 }
4076 }
4077
ClearCrossList(void)4078 void ClearCrossList(void)
4079 {
4080 IterTree(&(FirstSymbol->Tree), ClearCrossList_CNode, NULL);
4081 }
4082
4083 /*--------------------------------------------------------------------------*/
4084
GetLocHandle(void)4085 LongInt GetLocHandle(void)
4086 {
4087 return LocHandleCnt++;
4088 }
4089
PushLocHandle(LongInt NewLoc)4090 void PushLocHandle(LongInt NewLoc)
4091 {
4092 PLocHandle NewLocHandle;
4093
4094 NewLocHandle = (PLocHandle) malloc(sizeof(TLocHeap));
4095 NewLocHandle->Cont = MomLocHandle;
4096 NewLocHandle->Next = FirstLocHandle;
4097 FirstLocHandle = NewLocHandle; MomLocHandle = NewLoc;
4098 }
4099
PopLocHandle(void)4100 void PopLocHandle(void)
4101 {
4102 PLocHandle OldLocHandle;
4103
4104 OldLocHandle = FirstLocHandle;
4105 if (!OldLocHandle) return;
4106 MomLocHandle = OldLocHandle->Cont;
4107 FirstLocHandle = OldLocHandle->Next;
4108 free(OldLocHandle);
4109 }
4110
ClearLocStack()4111 void ClearLocStack()
4112 {
4113 while (MomLocHandle != -1)
4114 PopLocHandle();
4115 }
4116
4117 /*--------------------------------------------------------------------------*/
4118
PrintRegList_PNode(PTree Tree,void * pData)4119 static void PrintRegList_PNode(PTree Tree, void *pData)
4120 {
4121 PSymbolEntry Node = (PSymbolEntry) Tree;
4122
4123 if (Node->SymWert.Typ == TempReg)
4124 {
4125 TListContext *pContext = (TListContext*) pData;
4126 String tmp, tmp2;
4127
4128 if (Node->SymWert.Contents.RegDescr.Dissect)
4129 Node->SymWert.Contents.RegDescr.Dissect(tmp2, sizeof(tmp2), Node->SymWert.Contents.RegDescr.Reg, Node->SymSize);
4130 else
4131 *tmp2 = '\0';
4132 *tmp = '\0';
4133 if (Tree->Attribute != -1)
4134 as_snprcatf(tmp, sizeof(tmp), "[%s]", GetSectionName(Tree->Attribute));
4135 as_snprcatf(tmp, sizeof(tmp), "%c%s --> %s", Node->Used ? ' ' : '*', Tree->Name, tmp2);
4136 if ((int)strlen(tmp) > pContext->cwidth - 3)
4137 {
4138 if (*pContext->Zeilenrest)
4139 WrLstLine(pContext->Zeilenrest);
4140 *pContext->Zeilenrest = '\0';
4141 WrLstLine(tmp);
4142 }
4143 else
4144 {
4145 strmaxcat(tmp, Blanks(pContext->cwidth - 3 - strlen(tmp)), STRINGSIZE);
4146 if (!*pContext->Zeilenrest)
4147 strcpy(pContext->Zeilenrest, tmp);
4148 else
4149 {
4150 strcat(pContext->Zeilenrest, " | ");
4151 strcat(pContext->Zeilenrest, tmp);
4152 WrLstLine(pContext->Zeilenrest);
4153 *pContext->Zeilenrest = '\0';
4154 }
4155 }
4156 pContext->Sum++;
4157 if (!Node->Used)
4158 pContext->USum++;
4159 }
4160 }
4161
PrintRegDefs(void)4162 void PrintRegDefs(void)
4163 {
4164 String buf;
4165 LongInt ActPageWidth;
4166 TListContext Context;
4167
4168 if (!RegistersDefined)
4169 return;
4170
4171 NewPage(ChapDepth, True);
4172 WrLstLine(getmessage(Num_ListRegDefListHead1));
4173 WrLstLine(getmessage(Num_ListRegDefListHead2));
4174 WrLstLine("");
4175
4176 Context.Zeilenrest[0] = '\0';
4177 Context.Sum = Context.USum = 0;
4178 ActPageWidth = (PageWidth == 0) ? 80 : PageWidth;
4179 Context.cwidth = ActPageWidth >> 1;
4180 IterTree((PTree)FirstSymbol, PrintRegList_PNode, &Context);
4181
4182 if (*Context.Zeilenrest)
4183 WrLstLine(Context.Zeilenrest);
4184 WrLstLine("");
4185 as_snprintf(buf, sizeof(buf), "%7ld%s",
4186 (long) Context.Sum,
4187 getmessage((Context.Sum == 1) ? Num_ListRegDefSumMsg : Num_ListRegDefSumsMsg));
4188 WrLstLine(buf);
4189 as_snprintf(buf, sizeof(buf), "%7ld%s",
4190 (long)Context.USum,
4191 getmessage((Context.USum == 1) ? Num_ListRegDefUSumMsg : Num_ListRegDefUSumsMsg));
4192 WrLstLine("");
4193 }
4194
4195 /*--------------------------------------------------------------------------*/
4196
ClearCodepages(void)4197 void ClearCodepages(void)
4198 {
4199 PTransTable Old;
4200
4201 while (TransTables)
4202 {
4203 Old = TransTables;
4204 TransTables = Old->Next;
4205 free(Old->Name);
4206 free(Old->Table);
4207 free(Old);
4208 }
4209 }
4210
PrintCodepages(void)4211 void PrintCodepages(void)
4212 {
4213 char buf[500];
4214 PTransTable Table;
4215 int z, cnt, cnt2;
4216
4217 NewPage(ChapDepth, True);
4218 WrLstLine(getmessage(Num_ListCodepageListHead1));
4219 WrLstLine(getmessage(Num_ListCodepageListHead2));
4220 WrLstLine("");
4221
4222 cnt2 = 0;
4223 for (Table = TransTables; Table; Table = Table->Next)
4224 {
4225 for (z = cnt = 0; z < 256; z++)
4226 if (Table->Table[z] != z)
4227 cnt++;
4228 as_snprintf(buf, sizeof(buf), "%s (%d%s)", Table->Name, cnt,
4229 getmessage((cnt == 1) ? Num_ListCodepageChange : Num_ListCodepagePChange));
4230 WrLstLine(buf);
4231 cnt2++;
4232 }
4233 WrLstLine("");
4234 as_snprintf(buf, sizeof(buf), "%d%s", cnt2,
4235 getmessage((cnt2 == 1) ? Num_ListCodepageSumMsg : Num_ListCodepageSumsMsg));
4236 WrLstLine(buf);
4237 }
4238
4239 /*--------------------------------------------------------------------------*/
4240
asmpars_init(void)4241 void asmpars_init(void)
4242 {
4243 tIntTypeDef *pCurr;
4244
4245 serr = (char*)malloc(sizeof(char) * STRINGSIZE);
4246 snum = (char*)malloc(sizeof(char) * STRINGSIZE);
4247 FirstDefSymbol = NULL;
4248 FirstFunction = NULL;
4249 BalanceTrees = False;
4250
4251 for (pCurr = IntTypeDefs; pCurr < IntTypeDefs + (sizeof(IntTypeDefs) / sizeof(*IntTypeDefs)); pCurr++)
4252 {
4253 unsigned SignType = Hi(pCurr->SignAndWidth);
4254 unsigned Bits, Cnt;
4255
4256 Bits = Lo(pCurr->SignAndWidth) - ((SignType == 0x80) ? 1 : 0);
4257 for (Cnt = 0, pCurr->Mask = 0; Cnt < Bits; Cnt++)
4258 pCurr->Mask = (pCurr->Mask << 1) | 1;
4259
4260 pCurr->Max = (LargeInt)pCurr->Mask;
4261
4262 switch (SignType & 0xc0)
4263 {
4264 case 0x80:
4265 pCurr->Min = -pCurr->Max - 1;
4266 break;
4267 case 0xc0:
4268 pCurr->Min = (LargeInt)(pCurr->Mask / 2);
4269 pCurr->Min = -pCurr->Min - 1;
4270 break;
4271 default:
4272 pCurr->Min = 0;
4273 break;
4274 }
4275 }
4276
4277 LastGlobSymbol = (char*)malloc(sizeof(char) * STRINGSIZE);
4278 }
4279