Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* asmerr.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Error Message Writing                                                     */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11.  
  12. #include "stdinc.h"
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include <stdarg.h>
  16.  
  17. #include "asmdef.h"
  18. #include "asmsub.h"
  19. #include "asmpars.h"
  20. #include "console.h"
  21. #include "strutil.h"
  22. #include "nlmessages.h"
  23. #include "stdhandl.h"
  24. #include "as.h"
  25. #include "as.rsc"
  26. #include "ioerrs.h"
  27. #include "cmdarg.h"
  28. #include "asmallg.h"
  29. #include "asmerr.h"
  30.  
  31. typedef struct sExpectError
  32. {
  33.   struct sExpectError *pNext;
  34.   tErrorNum Num;
  35. } tExpectError;
  36.  
  37. Word ErrorCount, WarnCount;
  38. static tExpectError *pExpectErrors = NULL;
  39. static Boolean InExpect = False;
  40. static Boolean treat_warnings_as_errors,
  41.                warn_sign_extension,
  42.                def_warn_relative,
  43.                def_warn_relative_set,
  44.                warn_relative;
  45.  
  46. static void ClearExpectErrors(void)
  47. {
  48.   tExpectError *pOld;
  49.  
  50.   while (pExpectErrors)
  51.   {
  52.     pOld = pExpectErrors;
  53.     pExpectErrors = pExpectErrors->pNext;
  54.     free(pOld);
  55.   }
  56. }
  57.  
  58. static void AddExpectError(tExpectError *pExpectError)
  59. {
  60.   pExpectError->pNext = pExpectErrors;
  61.   pExpectErrors = pExpectError;
  62. }
  63.  
  64. /*!------------------------------------------------------------------------
  65.  * \fn     FindAndTakeExpectError(tErrorNum Num)
  66.  * \brief  check whether a certain error was expected
  67.  * \param  Num number of error message that was expected
  68.  * \return True if ther was an expectation
  69.  * ------------------------------------------------------------------------ */
  70.  
  71. Boolean FindAndTakeExpectError(tErrorNum Num)
  72. {
  73.   tExpectError *pRun, *pPrev;
  74.  
  75.   for (pRun = pExpectErrors, pPrev = NULL; pRun; pPrev = pRun, pRun = pRun->pNext)
  76.     if (Num == pRun->Num)
  77.     {
  78.       if (pPrev)
  79.         pPrev->pNext = pRun->pNext;
  80.       else
  81.         pExpectErrors = pRun->pNext;
  82.       free(pRun);
  83.       return True;
  84.     }
  85.   return False;
  86. }
  87.  
  88. /*!------------------------------------------------------------------------
  89.  * \fn     registered_test_and_set(unsigned mask)
  90.  * \brief  check whether on/off insn is registered first time during pass
  91.  * \param  mask insn to test
  92.  * \return mask if first time, otherwise 0
  93.  * ------------------------------------------------------------------------ */
  94.  
  95. enum
  96. {
  97.   e_onoff_reg_warn_relative = 1 << 0
  98. };
  99.  
  100. static unsigned registered_test_and_set(unsigned mask)
  101. {
  102.   static unsigned warn_registered;
  103.  
  104.   unsigned curr = warn_registered;
  105.   warn_registered |= mask;
  106.   return curr & mask;
  107. }
  108.  
  109. /*!------------------------------------------------------------------------
  110.  * \fn     asmerr_warn_relative_add(Boolean def_value)
  111.  * \brief  register on/off command to warn about possible relative jump
  112.  * \param  def_value to set as default
  113.  * ------------------------------------------------------------------------ */
  114.  
  115. #define WarnRelativeCmdName "WARNRELATIVE"
  116. #define WarnRelativeSymName "WARNRELATIVE"
  117.  
  118. void asmerr_warn_relative_add(void)
  119. {
  120.   if (!registered_test_and_set(e_onoff_reg_warn_relative))
  121.     SetFlag(&warn_relative, WarnRelativeSymName, def_warn_relative_set ? def_warn_relative : False);
  122.   AddONOFF(WarnRelativeCmdName, &warn_relative, WarnRelativeSymName, False);
  123. }
  124.  
  125. /*!------------------------------------------------------------------------
  126.  * \fn     GenLineMarker(char *pDest, unsigned DestSize, char Marker, const struct sLineComp *pLineComp, * const char *pPrefix)
  127.  * \brief  print a line, optionally with a marking of a component below
  128.  * \param  pDest where to write
  129.  * \param  DestSize destination buffer size
  130.  * \param  Marker character to use for marking
  131.  * \param  pLineComp position and length of optional marker
  132.  * \param  pPrefix what to print before (under)line
  133.  * ------------------------------------------------------------------------ */
  134.  
  135. static void GenLineMarker(char *pDest, unsigned DestSize, char Marker, const struct sLineComp *pLineComp, const char *pPrefix)
  136. {
  137.   char *pRun;
  138.   int z;
  139.  
  140.   strmaxcpy(pDest, pPrefix, DestSize);
  141.   pRun = pDest + strlen(pDest);
  142.  
  143.   for (z = 0; (z < pLineComp->StartCol) && (pRun - pDest + 1 < (int)DestSize); z++)
  144.     *pRun++ = ' ';
  145.   for (z = 0; (z < (int)pLineComp->Len) && (pRun - pDest + 1 < (int)DestSize); z++)
  146.     *pRun++ = Marker;
  147.   *pRun = '\0';
  148. }
  149.  
  150. /*!------------------------------------------------------------------------
  151.  * \fn     GenLineForMarking(char *pDest, unsigned DestSize, const char *pSrc, const char *pPrefix)
  152.  * \brief  generate a line, in compressed form for optional marking of a component below
  153.  * \param  pDest where to write
  154.  * \param  DestSize destination buffer size
  155.  * \param  pSrc line to print/underline
  156.  * \param  pPrefix what to print before (under)line
  157.  * ------------------------------------------------------------------------ */
  158.  
  159. static void GenLineForMarking(char *pDest, unsigned DestSize, const char *pSrc, const char *pPrefix)
  160. {
  161.   char *pRun;
  162.  
  163.   strmaxcpy(pDest, pPrefix, DestSize);
  164.   pRun = pDest + strlen(pDest);
  165.  
  166.   /* replace TABs in line with spaces - column counting counts TAB as one character */
  167.  
  168.   for (; *pSrc && (pRun - pDest + 1 < (int)DestSize); pSrc++)
  169.     *pRun++ = TabCompressed(*pSrc);
  170.   *pRun = '\0';
  171. }
  172.  
  173. /*!------------------------------------------------------------------------
  174.  * \fn     EmergencyStop(void)
  175.  * \brief  instantly stop upon fatal error
  176.  * ------------------------------------------------------------------------ */
  177.  
  178. static void EmergencyStop(void)
  179. {
  180.   CloseIfOpen(&ErrorFile);
  181.   CloseIfOpen(&LstFile);
  182.   if (ShareMode != 0)
  183.   {
  184.     CloseIfOpen(&ShareFile);
  185.     unlink(ShareName);
  186.   }
  187.   if (MacProOutput)
  188.   {
  189.     CloseIfOpen(&MacProFile);
  190.     unlink(MacProName);
  191.   }
  192.   if (MacroOutput)
  193.   {
  194.     CloseIfOpen(&MacroFile);
  195.     unlink(MacroName);
  196.   }
  197.   if (MakeDebug)
  198.     CloseIfOpen(&Debug);
  199.   if (CodeOutput)
  200.   {
  201.     CloseIfOpen(&PrgFile);
  202.     unlink(OutName);
  203.   }
  204. }
  205.  
  206. /*!------------------------------------------------------------------------
  207.  * \fn     ErrorNum2String(tErrorNum Num, char Buf, int BufSize)
  208.  * \brief  convert error # to string
  209.  * \param  Num numeric error
  210.  * \param  Buf buffer for complex messages
  211.  * \param  BufSize capacity of Buf
  212.  * \return * to message
  213.  * ------------------------------------------------------------------------ */
  214.  
  215. static const char *ErrorNum2String(tErrorNum Num, char *Buf, int BufSize)
  216. {
  217.   int msgno = -1;
  218.  
  219.   *Buf = '\0';
  220.   switch (Num)
  221.   {
  222.     case ErrNum_UselessDisp:
  223.       msgno = Num_ErrMsgUselessDisp; break;
  224.     case ErrNum_ShortAddrPossible:
  225.       msgno = Num_ErrMsgShortAddrPossible; break;
  226.     case ErrNum_ShortJumpPossible:
  227.       msgno = Num_ErrMsgShortJumpPossible; break;
  228.     case ErrNum_RelJumpPossible:
  229.       msgno = Num_ErrMsgRelJumpPossible; break;
  230.     case ErrNum_NoShareFile:
  231.       msgno = Num_ErrMsgNoShareFile; break;
  232.     case ErrNum_BigDecFloat:
  233.       msgno = Num_ErrMsgBigDecFloat; break;
  234.     case ErrNum_PrivOrder:
  235.       msgno = Num_ErrMsgPrivOrder; break;
  236.     case ErrNum_DistNull:
  237.       msgno = Num_ErrMsgDistNull; break;
  238.     case ErrNum_WrongSegment:
  239.       msgno = Num_ErrMsgWrongSegment; break;
  240.     case ErrNum_InAccSegment:
  241.       msgno = Num_ErrMsgInAccSegment; break;
  242.     case ErrNum_PhaseErr:
  243.       msgno = Num_ErrMsgPhaseErr; break;
  244.     case ErrNum_Overlap:
  245.       msgno = Num_ErrMsgOverlap; break;
  246.     case ErrNum_OverlapReg:
  247.       msgno = Num_ErrMsgOverlapReg; break;
  248.     case ErrNum_NoCaseHit:
  249.       msgno = Num_ErrMsgNoCaseHit; break;
  250.     case ErrNum_InAccPage:
  251.       msgno = Num_ErrMsgInAccPage; break;
  252.     case ErrNum_RMustBeEven:
  253.       msgno = Num_ErrMsgRMustBeEven; break;
  254.     case ErrNum_Obsolete:
  255.       msgno = Num_ErrMsgObsolete; break;
  256.     case ErrNum_Unpredictable:
  257.       msgno = Num_ErrMsgUnpredictable; break;
  258.     case ErrNum_AlphaNoSense:
  259.       msgno = Num_ErrMsgAlphaNoSense; break;
  260.     case ErrNum_Senseless:
  261.       msgno = Num_ErrMsgSenseless; break;
  262.     case ErrNum_RepassUnknown:
  263.       msgno = Num_ErrMsgRepassUnknown; break;
  264.     case  ErrNum_AddrNotAligned:
  265.       msgno = Num_ErrMsgAddrNotAligned; break;
  266.     case ErrNum_IOAddrNotAllowed:
  267.       msgno = Num_ErrMsgIOAddrNotAllowed; break;
  268.     case ErrNum_Pipeline:
  269.       msgno = Num_ErrMsgPipeline; break;
  270.     case ErrNum_DoubleAdrRegUse:
  271.       msgno = Num_ErrMsgDoubleAdrRegUse; break;
  272.     case ErrNum_NotBitAddressable:
  273.       msgno = Num_ErrMsgNotBitAddressable; break;
  274.     case ErrNum_StackNotEmpty:
  275.       msgno = Num_ErrMsgStackNotEmpty; break;
  276.     case ErrNum_NULCharacter:
  277.       msgno = Num_ErrMsgNULCharacter; break;
  278.     case ErrNum_PageCrossing:
  279.       msgno = Num_ErrMsgPageCrossing; break;
  280.     case ErrNum_WUnderRange:
  281.       msgno = Num_ErrMsgWUnderRange; break;
  282.     case ErrNum_WOverRange:
  283.       msgno = Num_ErrMsgWOverRange; break;
  284.     case ErrNum_NegDUP:
  285.       msgno = Num_ErrMsgNegDUP; break;
  286.     case ErrNum_ConvIndX:
  287.       msgno = Num_ErrMsgConvIndX; break;
  288.     case ErrNum_NullResMem:
  289.       msgno = Num_ErrMsgNullResMem; break;
  290.     case ErrNum_BitNumberTruncated:
  291.       msgno = Num_ErrMsgBitNumberTruncated; break;
  292.     case ErrNum_InvRegisterPointer:
  293.       msgno = Num_ErrMsgInvRegisterPointer; break;
  294.     case ErrNum_MacArgRedef:
  295.       msgno = Num_ErrMsgMacArgRedef; break;
  296.     case ErrNum_Deprecated:
  297.       msgno = Num_ErrMsgDeprecated; break;
  298.     case ErrNum_SrcLEThanDest:
  299.       msgno = Num_ErrMsgSrcLEThanDest; break;
  300.     case ErrNum_TrapValidInstruction:
  301.       msgno = Num_ErrMsgTrapValidInstruction; break;
  302.     case ErrNum_PaddingAdded:
  303.       msgno = Num_ErrMsgPaddingAdded; break;
  304.     case ErrNum_RegNumWraparound:
  305.       msgno = Num_ErrMsgRegNumWraparound; break;
  306.     case ErrNum_IndexedForIndirect:
  307.       msgno = Num_ErrMsgIndexedForIndirect; break;
  308.     case ErrNum_NotInNormalMode:
  309.       msgno = Num_ErrMsgNotInNormalMode; break;
  310.     case ErrNum_NotInPanelMode:
  311.       msgno = Num_ErrMsgNotInPanelMode; break;
  312.     case ErrNum_ArgOutOfRange:
  313.       msgno = Num_ErrMsgArgOutOfRange; break;
  314.     case ErrNum_TrySkipMultiwordInstruction:
  315.       msgno = Num_ErrMsgTrySkipMultiwordInstruction; break;
  316.     case ErrNum_SignExtension:
  317.       msgno = Num_ErrMsgSignExtension; break;
  318.     case ErrNum_MeansE:
  319.       msgno = Num_ErrMsgMeansE; break;
  320.     case ErrNum_NeedShortIO:
  321.       msgno = Num_ErrMsgNeedShortIO; break;
  322.     case ErrNum_CaseWrongArgCnt:
  323.       msgno = Num_ErrMsgCaseWrongArgCnt; break;
  324.     case ErrNum_ReplacedByNOP:
  325.       msgno = Num_ErrMsgReplacedByNOP; break;
  326.     case ErrNum_TreatedAsVector:
  327.       msgno = Num_ErrMsgTreatedAsVector; break;
  328.     case ErrNum_LargeIntAsFloat:
  329.       msgno = Num_ErrMsgLargeIntAsFloat; break;
  330.     case ErrNum_DoubleDef:
  331.       msgno = Num_ErrMsgDoubleDef; break;
  332.     case ErrNum_SymbolUndef:
  333.       msgno = Num_ErrMsgSymbolUndef; break;
  334.     case ErrNum_InvSymName:
  335.       msgno = Num_ErrMsgInvSymName; break;
  336.     case ErrNum_RsvdSymName:
  337.       msgno = Num_ErrMsgRsvdSymName; break;
  338.     case ErrNum_InvFormat:
  339.       msgno = Num_ErrMsgInvFormat; break;
  340.     case ErrNum_UseLessAttr:
  341.       msgno = Num_ErrMsgUseLessAttr; break;
  342.     case ErrNum_TooLongAttr:
  343.       msgno = Num_ErrMsgTooLongAttr; break;
  344.     case ErrNum_UndefAttr:
  345.       msgno = Num_ErrMsgUndefAttr; break;
  346.     case ErrNum_WrongArgCnt:
  347.       msgno = Num_ErrMsgWrongArgCnt; break;
  348.     case ErrNum_CannotSplitArg:
  349.       msgno = Num_ErrMsgCannotSplitArg; break;
  350.     case ErrNum_WrongOptCnt:
  351.       msgno = Num_ErrMsgWrongOptCnt; break;
  352.     case ErrNum_OnlyImmAddr:
  353.       msgno = Num_ErrMsgOnlyImmAddr; break;
  354.     case ErrNum_InvOpSize:
  355.       msgno = Num_ErrMsgInvOpSize; break;
  356.     case ErrNum_ConfOpSizes:
  357.       msgno = Num_ErrMsgConfOpSizes; break;
  358.     case ErrNum_UndefOpSizes:
  359.       msgno = Num_ErrMsgUndefOpSizes; break;
  360.     case ErrNum_StringOrIntButFloat:
  361.       msgno = Num_ErrMsgStringOrIntButFloat; break;
  362.     case ErrNum_IntButFloat:
  363.       msgno = Num_ErrMsgIntButFloat; break;
  364.     case ErrNum_FloatButString:
  365.       msgno = Num_ErrMsgFloatButString; break;
  366.     case ErrNum_OpTypeMismatch:
  367.       msgno = Num_ErrMsgOpTypeMismatch; break;
  368.     case ErrNum_StringButInt:
  369.       msgno = Num_ErrMsgStringButInt; break;
  370.     case ErrNum_StringButFloat:
  371.       msgno = Num_ErrMsgStringButFloat; break;
  372.     case ErrNum_TooManyArgs:
  373.       msgno = Num_ErrMsgTooManyArgs; break;
  374.     case ErrNum_IntButString:
  375.       msgno = Num_ErrMsgIntButString; break;
  376.     case ErrNum_IntOrFloatButString:
  377.       msgno = Num_ErrMsgIntOrFloatButString; break;
  378.     case ErrNum_ExpectString:
  379.       msgno = Num_ErrMsgExpectString; break;
  380.     case ErrNum_ExpectInt:
  381.       msgno = Num_ErrMsgExpectInt; break;
  382.     case ErrNum_StringOrIntOrFloatButReg:
  383.       msgno = Num_ErrMsgStringOrIntOrFloatButReg; break;
  384.     case ErrNum_ExpectIntOrString:
  385.       msgno = Num_ErrMsgExpectIntOrString; break;
  386.     case ErrNum_ExpectReg:
  387.       msgno = Num_ErrMsgExpectReg; break;
  388.     case ErrNum_RegWrongTarget:
  389.       msgno = Num_ErrMsgRegWrongTarget; break;
  390.     case ErrNum_FloatButInt:
  391.       msgno = Num_ErrMsgFloatButInt; break;
  392.     case ErrNum_NoRelocs:
  393.       msgno = Num_ErrMsgNoRelocs; break;
  394.     case ErrNum_IntOrFloatButReg:
  395.       msgno = Num_ErrMsgIntOrFloatButReg; break;
  396.     case ErrNum_IntOrStringButReg:
  397.       msgno = Num_ErrMsgIntOrStringButReg; break;
  398.     case ErrNum_StringTooLong:
  399.       msgno = Num_ErrMsgStringTooLong; break;
  400.     case ErrNum_IntButReg:
  401.       msgno = Num_ErrMsgIntButReg; break;
  402.     case ErrNum_UnresRelocs:
  403.       msgno = Num_ErrMsgUnresRelocs; break;
  404.     case ErrNum_Unexportable:
  405.       msgno = Num_ErrMsgUnexportable; break;
  406.     case ErrNum_UnknownInstruction:
  407.       msgno = Num_ErrMsgUnknownInstruction; break;
  408.     case ErrNum_BrackErr:
  409.       msgno = Num_ErrMsgBrackErr; break;
  410.     case ErrNum_DivByZero:
  411.       msgno = Num_ErrMsgDivByZero; break;
  412.     case ErrNum_UnderRange:
  413.       msgno = Num_ErrMsgUnderRange; break;
  414.     case ErrNum_OverRange:
  415.       msgno = Num_ErrMsgOverRange; break;
  416.     case ErrNum_NotPwr2:
  417.       msgno = Num_ErrMsgNotPwr2; break;
  418.     case ErrNum_InvalidDecDigit:
  419.       msgno = Num_ErrMsgInvalidDecDigit; break;
  420.     case ErrNum_DecStringTooLong:
  421.       msgno = Num_ErrMsgDecStringTooLong; break;
  422.     case ErrNum_NotAligned:
  423.       msgno = Num_ErrMsgNotAligned; break;
  424.     case ErrNum_DistTooBig:
  425.       msgno = Num_ErrMsgDistTooBig; break;
  426.     case ErrNum_TargOnDiffPage:
  427.       msgno = Num_ErrMsgTargOnDiffPage; break;
  428.     case ErrNum_InAccReg:
  429.       msgno = Num_ErrMsgInAccReg; break;
  430.     case ErrNum_NoShortAddr:
  431.       msgno = Num_ErrMsgNoShortAddr; break;
  432.     case ErrNum_InvAddrMode:
  433.       msgno = Num_ErrMsgInvAddrMode; break;
  434.     case ErrNum_AddrMustBeEven:
  435.       msgno = Num_ErrMsgAddrMustBeEven; break;
  436.     case ErrNum_AddrMustBeAligned:
  437.       msgno = Num_ErrMsgAddrMustBeAligned; break;
  438.     case ErrNum_InvParAddrMode:
  439.       msgno = Num_ErrMsgInvParAddrMode; break;
  440.     case ErrNum_UndefCond:
  441.       msgno = Num_ErrMsgUndefCond; break;
  442.     case ErrNum_IncompCond:
  443.       msgno = Num_ErrMsgIncompCond; break;
  444.     case ErrNum_UnknownFlag:
  445.       msgno = Num_ErrMsgUnknownFlag; break;
  446.     case ErrNum_DuplicateFlag:
  447.       msgno = Num_ErrMsgDuplicateFlag; break;
  448.     case ErrNum_UnknownInt:
  449.       msgno = Num_ErrMsgUnknownInt; break;
  450.     case ErrNum_DuplicateInt:
  451.       msgno = Num_ErrMsgDuplicateInt; break;
  452.     case ErrNum_JmpDistTooBig:
  453.       msgno = Num_ErrMsgJmpDistTooBig; break;
  454.     case ErrNum_JmpDistIsZero:
  455.       msgno = Num_ErrMsgJmpDistIsZero; break;
  456.     case ErrNum_DistIsOdd:
  457.       msgno = Num_ErrMsgDistIsOdd; break;
  458.     case ErrNum_SkipTargetMismatch:
  459.       msgno = Num_ErrMsgSkipTargetMismatch; break;
  460.     case ErrNum_InvShiftArg:
  461.       msgno = Num_ErrMsgInvShiftArg; break;
  462.     case ErrNum_Only1:
  463.       msgno = Num_ErrMsgOnly1; break;
  464.     case ErrNum_Range18:
  465.       msgno = Num_ErrMsgRange18; break;
  466.     case ErrNum_ShiftCntTooBig:
  467.       msgno = Num_ErrMsgShiftCntTooBig; break;
  468.     case ErrNum_InvRegList:
  469.       msgno = Num_ErrMsgInvRegList; break;
  470.     case ErrNum_InvCmpMode:
  471.       msgno = Num_ErrMsgInvCmpMode; break;
  472.     case ErrNum_InvCPUType:
  473.       msgno = Num_ErrMsgInvCPUType; break;
  474.     case ErrNum_InvFPUType:
  475.       msgno = Num_ErrMsgInvFPUType; break;
  476.     case ErrNum_InvPMMUType:
  477.       msgno = Num_ErrMsgInvPMMUType; break;
  478.     case ErrNum_InvCtrlReg:
  479.       msgno = Num_ErrMsgInvCtrlReg; break;
  480.     case ErrNum_InvReg:
  481.       msgno = Num_ErrMsgInvReg; break;
  482.     case ErrNum_DoubleReg:
  483.       msgno = Num_ErrMsgDoubleReg; break;
  484.     case ErrNum_RegBankMismatch:
  485.       msgno = Num_ErrMsgRegBankMismatch; break;
  486.     case ErrNum_UndefRegSize:
  487.       msgno = Num_ErrMsgUndefRegSize; break;
  488.     case ErrNum_InvOpOnReg:
  489.       msgno = Num_ErrMsgInvOpOnReg; break;
  490.     case ErrNum_NoSaveFrame:
  491.       msgno = Num_ErrMsgNoSaveFrame; break;
  492.     case ErrNum_NoRestoreFrame:
  493.       msgno = Num_ErrMsgNoRestoreFrame; break;
  494.     case ErrNum_UnknownMacArg:
  495.       msgno = Num_ErrMsgUnknownMacArg; break;
  496.     case ErrNum_MissEndif:
  497.       msgno = Num_ErrMsgMissEndif; break;
  498.     case ErrNum_InvIfConst:
  499.       msgno = Num_ErrMsgInvIfConst; break;
  500.     case ErrNum_DoubleSection:
  501.       msgno = Num_ErrMsgDoubleSection; break;
  502.     case ErrNum_InvSection:
  503.       msgno = Num_ErrMsgInvSection; break;
  504.     case ErrNum_MissingEndSect:
  505.       msgno = Num_ErrMsgMissingEndSect; break;
  506.     case ErrNum_WrongEndSect:
  507.       msgno = Num_ErrMsgWrongEndSect; break;
  508.     case ErrNum_NotInSection:
  509.       msgno = Num_ErrMsgNotInSection; break;
  510.     case ErrNum_UndefdForward:
  511.       msgno = Num_ErrMsgUndefdForward; break;
  512.     case ErrNum_ContForward:
  513.       msgno = Num_ErrMsgContForward; break;
  514.     case ErrNum_InvFuncArgCnt:
  515.       msgno = Num_ErrMsgInvFuncArgCnt; break;
  516.     case ErrNum_DupFuncArgName:
  517.       msgno = Num_ErrMsgDupFuncArgName; break;
  518.     case ErrNum_MsgMissingLTORG:
  519.       msgno = Num_ErrMsgMissingLTORG; break;
  520.     case ErrNum_InstructionNotSupported:
  521.       as_snprintf(Buf, BufSize, getmessage(Num_ErrMsgInstructionNotOnThisCPUSupported), MomCPUIdent);
  522.       break;
  523.     case ErrNum_FPUNotEnabled:
  524.       msgno = Num_ErrMsgFPUNotEnabled; break;
  525.     case ErrNum_PMMUNotEnabled:
  526.       msgno = Num_ErrMsgPMMUNotEnabled; break;
  527.     case ErrNum_FullPMMUNotEnabled:
  528.       msgno = Num_ErrMsgFullPMMUNotEnabled; break;
  529.     case ErrNum_Z80SyntaxNotEnabled:
  530.       msgno = Num_ErrMsgZ80SyntaxNotEnabled; break;
  531.     case ErrNum_Z80SyntaxExclusive:
  532.       msgno = Num_ErrMsgZ80SyntaxExclusive; break;
  533.     case ErrNum_FPUInstructionNotSupported:
  534.       as_snprintf(Buf, BufSize, getmessage(Num_ErrMsgInstructionNotOnThisFPUSupported), MomFPUIdent);
  535.       break;
  536.     case ErrNum_AddrModeNotSupported:
  537.       as_snprintf(Buf, BufSize, getmessage(Num_ErrMsgAddrModeNotOnThisCPUSupported), MomCPUIdent);
  538.       break;
  539.     case ErrNum_CustomNotEnabled:
  540.       msgno = Num_ErrMsgCustomNotEnabled; break;
  541.     case ErrNum_InvBitPos:
  542.       msgno = Num_ErrMsgInvBitPos; break;
  543.     case ErrNum_OnlyOnOff:
  544.       msgno = Num_ErrMsgOnlyOnOff; break;
  545.     case ErrNum_StackEmpty:
  546.       msgno = Num_ErrMsgStackEmpty; break;
  547.     case ErrNum_NotOneBit:
  548.       msgno = Num_ErrMsgNotOneBit; break;
  549.     case ErrNum_MissingStruct:
  550.       msgno = Num_ErrMsgMissingStruct; break;
  551.     case ErrNum_OpenStruct:
  552.       msgno = Num_ErrMsgOpenStruct; break;
  553.     case ErrNum_WrongStruct:
  554.       msgno = Num_ErrMsgWrongStruct; break;
  555.     case ErrNum_PhaseDisallowed:
  556.       msgno = Num_ErrMsgPhaseDisallowed; break;
  557.     case ErrNum_InvStructDir:
  558.       msgno = Num_ErrMsgInvStructDir; break;
  559.     case ErrNum_DoubleStruct:
  560.       msgno = Num_ErrMsgDoubleStruct; break;
  561.     case ErrNum_UnresolvedStructRef:
  562.       msgno = Num_ErrMsgUnresolvedStructRef; break;
  563.     case ErrNum_DuplicateStructElem:
  564.       msgno = Num_ErrMsgDuplicateStructElem; break;
  565.     case ErrNum_NotRepeatable:
  566.       msgno = Num_ErrMsgNotRepeatable; break;
  567.     case ErrNum_ShortRead:
  568.       msgno = Num_ErrMsgShortRead; break;
  569.     case ErrNum_UnknownCodepage:
  570.       msgno = Num_ErrMsgUnknownCodepage; break;
  571.     case ErrNum_RomOffs063:
  572.       msgno = Num_ErrMsgRomOffs063; break;
  573.     case ErrNum_InvFCode:
  574.       msgno = Num_ErrMsgInvFCode; break;
  575.     case ErrNum_InvFMask:
  576.       msgno = Num_ErrMsgInvFMask; break;
  577.     case ErrNum_InvMMUReg:
  578.       msgno = Num_ErrMsgInvMMUReg; break;
  579.     case ErrNum_Level07:
  580.       msgno = Num_ErrMsgLevel07; break;
  581.     case ErrNum_InvBitMask:
  582.       msgno = Num_ErrMsgInvBitMask; break;
  583.     case ErrNum_InvRegPair:
  584.       msgno = Num_ErrMsgInvRegPair; break;
  585.     case ErrNum_OpenMacro:
  586.       msgno = Num_ErrMsgOpenMacro; break;
  587.     case ErrNum_OpenIRP:
  588.       msgno = Num_ErrMsgOpenIRP; break;
  589.     case ErrNum_OpenIRPC:
  590.       msgno = Num_ErrMsgOpenIRPC; break;
  591.     case ErrNum_OpenREPT:
  592.       msgno = Num_ErrMsgOpenREPT; break;
  593.     case ErrNum_OpenWHILE:
  594.       msgno = Num_ErrMsgOpenWHILE; break;
  595.     case ErrNum_EXITMOutsideMacro:
  596.       msgno = Num_ErrMsgEXITMOutsideMacro; break;
  597.     case ErrNum_TooManyMacParams:
  598.       msgno = Num_ErrMsgTooManyMacParams; break;
  599.     case ErrNum_UndefKeyArg:
  600.       msgno = Num_ErrMsgUndefKeyArg; break;
  601.     case ErrNum_NoPosArg:
  602.       msgno = Num_ErrMsgNoPosArg; break;
  603.     case ErrNum_DoubleMacro:
  604.       msgno = Num_ErrMsgDoubleMacro; break;
  605.     case ErrNum_FirstPassCalc:
  606.       msgno = Num_ErrMsgFirstPassCalc; break;
  607.     case ErrNum_TooManyNestedIfs:
  608.       msgno = Num_ErrMsgTooManyNestedIfs; break;
  609.     case ErrNum_MissingIf:
  610.       msgno = Num_ErrMsgMissingIf; break;
  611.     case ErrNum_RekMacro:
  612.       msgno = Num_ErrMsgRekMacro; break;
  613.     case ErrNum_UnknownFunc:
  614.       msgno = Num_ErrMsgUnknownFunc; break;
  615.     case ErrNum_InvFuncArg:
  616.       msgno = Num_ErrMsgInvFuncArg; break;
  617.     case ErrNum_FloatOverflow:
  618.       msgno = Num_ErrMsgFloatOverflow; break;
  619.     case ErrNum_InvArgPair:
  620.       msgno = Num_ErrMsgInvArgPair; break;
  621.     case ErrNum_NotOnThisAddress:
  622.       msgno = Num_ErrMsgNotOnThisAddress; break;
  623.     case ErrNum_NotFromThisAddress:
  624.       msgno = Num_ErrMsgNotFromThisAddress; break;
  625.     case ErrNum_JmpTargOnDiffPage:
  626.       msgno = Num_ErrMsgJmpTargOnDiffPage; break;
  627.     case ErrNum_TargOnDiffSection:
  628.       msgno = Num_ErrMsgTargOnDiffSection; break;
  629.     case ErrNum_CodeOverflow:
  630.       msgno = Num_ErrMsgCodeOverflow; break;
  631.     case ErrNum_AdrOverflow:
  632.       msgno = Num_ErrMsgAdrOverflow; break;
  633.     case ErrNum_MixDBDS:
  634.       msgno = Num_ErrMsgMixDBDS; break;
  635.     case ErrNum_NotInStruct:
  636.       msgno = Num_ErrMsgNotInStruct; break;
  637.     case ErrNum_ParNotPossible:
  638.       msgno = Num_ErrMsgParNotPossible; break;
  639.     case ErrNum_InvSegment:
  640.       msgno = Num_ErrMsgInvSegment; break;
  641.     case ErrNum_UnknownSegment:
  642.       msgno = Num_ErrMsgUnknownSegment; break;
  643.     case ErrNum_UnknownSegReg:
  644.       msgno = Num_ErrMsgUnknownSegReg; break;
  645.     case ErrNum_InvString:
  646.       msgno = Num_ErrMsgInvString; break;
  647.     case ErrNum_InvRegName:
  648.       msgno = Num_ErrMsgInvRegName; break;
  649.     case ErrNum_InvArg:
  650.       msgno = Num_ErrMsgInvArg; break;
  651.     case ErrNum_NoIndir:
  652.       msgno = Num_ErrMsgNoIndir; break;
  653.     case ErrNum_NotInThisSegment:
  654.       msgno = Num_ErrMsgNotInThisSegment; break;
  655.     case ErrNum_NotInMaxmode:
  656.       msgno = Num_ErrMsgNotInMaxmode; break;
  657.     case ErrNum_OnlyInMaxmode:
  658.       msgno = Num_ErrMsgOnlyInMaxmode; break;
  659.     case ErrNum_PackCrossBoundary:
  660.       msgno = Num_ErrMsgPackCrossBoundary; break;
  661.     case ErrNum_UnitMultipleUsed:
  662.       msgno = Num_ErrMsgUnitMultipleUsed; break;
  663.     case ErrNum_MultipleLongRead:
  664.       msgno = Num_ErrMsgMultipleLongRead; break;
  665.     case ErrNum_MultipleLongWrite:
  666.       msgno = Num_ErrMsgMultipleLongWrite; break;
  667.     case ErrNum_LongReadWithStore:
  668.       msgno = Num_ErrMsgLongReadWithStore; break;
  669.     case ErrNum_TooManyRegisterReads:
  670.       msgno = Num_ErrMsgTooManyRegisterReads; break;
  671.     case ErrNum_OverlapDests:
  672.       msgno = Num_ErrMsgOverlapDests; break;
  673.     case ErrNum_TooManyBranchesInExPacket:
  674.       msgno = Num_ErrMsgTooManyBranchesInExPacket; break;
  675.     case ErrNum_CannotUseUnit:
  676.       msgno = Num_ErrMsgCannotUseUnit; break;
  677.     case ErrNum_InvEscSequence:
  678.       msgno = Num_ErrMsgInvEscSequence; break;
  679.     case ErrNum_InvPrefixCombination:
  680.       msgno = Num_ErrMsgInvPrefixCombination; break;
  681.     case ErrNum_ConstantRedefinedAsVariable:
  682.       msgno = Num_ErrMsgConstantRedefinedAsVariable; break;
  683.     case ErrNum_VariableRedefinedAsConstant:
  684.       msgno = Num_ErrMsgVariableRedefinedAsConstant; break;
  685.     case ErrNum_StructNameMissing:
  686.       msgno = Num_ErrMsgStructNameMissing; break;
  687.     case ErrNum_EmptyArgument:
  688.       msgno = Num_ErrMsgEmptyArgument; break;
  689.     case ErrNum_Unimplemented:
  690.       msgno = Num_ErrMsgUnimplemented; break;
  691.     case ErrNum_FreestandingUnnamedStruct:
  692.       msgno = Num_ErrMsgFreestandingUnnamedStruct; break;
  693.     case ErrNum_STRUCTEndedByENDUNION:
  694.       msgno = Num_ErrMsgSTRUCTEndedByENDUNION; break;
  695.     case ErrNum_AddrOnDifferentPage:
  696.       msgno = Num_ErrMsgAddrOnDifferentPage; break;
  697.     case ErrNum_UnknownMacExpMod:
  698.       msgno = Num_ErrMsgUnknownMacExpMod; break;
  699.     case ErrNum_TooManyMacExpMod:
  700.       msgno = Num_ErrMsgTooManyMacExpMod; break;
  701.     case ErrNum_ConflictingMacExpMod:
  702.       msgno = Num_ErrMsgConflictingMacExpMod; break;
  703.     case ErrNum_InvalidPrepDir:
  704.       msgno = Num_ErrMsgInvalidPrepDir; break;
  705.     case ErrNum_ExpectedError:
  706.       msgno = Num_ErrMsgExpectedError; break;
  707.     case ErrNum_NoNestExpect:
  708.       msgno = Num_ErrMsgNoNestExpect; break;
  709.     case ErrNum_MissingENDEXPECT:
  710.       msgno = Num_ErrMsgMissingENDEXPECT; break;
  711.     case ErrNum_MissingEXPECT:
  712.       msgno = Num_ErrMsgMissingEXPECT; break;
  713.     case ErrNum_NoDefCkptReg:
  714.       msgno = Num_ErrMsgNoDefCkptReg; break;
  715.     case ErrNum_InvBitField:
  716.       msgno = Num_ErrMsgInvBitField; break;
  717.     case ErrNum_ArgValueMissing:
  718.       msgno = Num_ErrMsgArgValueMissing; break;
  719.     case ErrNum_UnknownArg:
  720.       msgno = Num_ErrMsgUnknownArg; break;
  721.     case ErrNum_IndexRegMustBe16Bit:
  722.       msgno = Num_ErrMsgIndexRegMustBe16Bit; break;
  723.     case ErrNum_IOAddrRegMustBe16Bit:
  724.       msgno = Num_ErrMsgIOAddrRegMustBe16Bit; break;
  725.     case ErrNum_SegAddrRegMustBe32Bit:
  726.       msgno = Num_ErrMsgSegAddrRegMustBe32Bit; break;
  727.     case ErrNum_NonSegAddrRegMustBe16Bit:
  728.       msgno = Num_ErrMsgNonSegAddrRegMustBe16Bit; break;
  729.     case ErrNum_InvStructArgument:
  730.       msgno = Num_ErrMsgInvStructArgument; break;
  731.     case ErrNum_TooManyArrayDimensions:
  732.       msgno = Num_ErrMsgTooManyArrayDimensions; break;
  733.     case ErrNum_InvIntFormat:
  734.       msgno = Num_ErrMsgInvIntFormat; break;
  735.     case ErrNum_InvIntFormatList:
  736.       msgno = Num_ErrMsgInvIntFormatList; break;
  737.     case ErrNum_InvScale:
  738.       msgno = Num_ErrMsgInvScale; break;
  739.     case ErrNum_ConfStringOpt:
  740.       msgno = Num_ErrMsgConfStringOpt; break;
  741.     case ErrNum_UnknownStringOpt:
  742.       msgno = Num_ErrMsgUnknownStringOpt; break;
  743.     case ErrNum_InvCacheInvMode:
  744.       msgno = Num_ErrMsgInvCacheInvMode; break;
  745.     case ErrNum_InvCfgList:
  746.       msgno = Num_ErrMsgInvCfgList; break;
  747.     case ErrNum_ConfBitBltOpt:
  748.       msgno = Num_ErrMsgConfBitBltOpt; break;
  749.     case ErrNum_UnknownBitBltOpt:
  750.       msgno = Num_ErrMsgUnknownBitBltOpt; break;
  751.     case ErrNum_InvCBAR:
  752.       msgno = Num_ErrMsgInvCBAR; break;
  753.     case ErrNum_InAccPageErr:
  754.       msgno = Num_ErrMsgInAccPageErr; break;
  755.     case ErrNum_InAccFieldErr:
  756.       msgno = Num_ErrMsgInAccFieldErr; break;
  757.     case ErrNum_TargInDiffField:
  758.       msgno = Num_ErrMsgTargInDiffField; break;
  759.     case ErrNum_InvCombination:
  760.       msgno = Num_ErrMsgInvCombination; break;
  761.     case ErrNum_UnmappedChar:
  762.       msgno = Num_ErrMsgUnmappedChar; break;
  763.     case ErrNum_NoTarget:
  764.       msgno = Num_ErrMsgNoTarget; break;
  765.     case ErrNum_MultiCharInvLength:
  766.       msgno = Num_ErrMsgMultiCharInvLength; break;
  767.     case ErrNum_InvDispLen:
  768.       msgno = Num_ErrMsgInvDispLen; break;
  769.     case ErrNum_InternalError:
  770.       msgno = Num_ErrMsgInternalError; break;
  771.     case ErrNum_OpeningFile:
  772.       msgno = Num_ErrMsgOpeningFile; break;
  773.     case ErrNum_ListWrError:
  774.       msgno = Num_ErrMsgListWrError; break;
  775.     case ErrNum_FileReadError:
  776.       msgno = Num_ErrMsgFileReadError; break;
  777.     case ErrNum_FileWriteError:
  778.       msgno = Num_ErrMsgFileWriteError; break;
  779.     case ErrNum_HeapOvfl:
  780.       msgno = Num_ErrMsgHeapOvfl; break;
  781.     case ErrNum_StackOvfl:
  782.       msgno = Num_ErrMsgStackOvfl; break;
  783.     case ErrNum_MaxIncLevelExceeded:
  784.       msgno = Num_ErrMsgMaxIncLevelExceeded; break;
  785.     case ErrNum_InvListHeadFormat:
  786.       msgno = Num_ErrMsgInvListHeadFormat; break;
  787.     case ErrNum_ListHeadFormatElemTooOften:
  788.       msgno = Num_ErrMsgListHeadFormatElemTooOften; break;
  789.     default:
  790.       as_snprintf(Buf, BufSize, "%s %d", getmessage(Num_ErrMsgIntError), (int) Num);
  791.   }
  792.   return (msgno != -1) ? getmessage(msgno) : Buf;
  793. }
  794.  
  795. /*!------------------------------------------------------------------------
  796.  * \fn     WrErrorString(const char *pMessage, const char *pAdd, Boolean Warning, Boolean Fatal,
  797.                          const char *pExtendError, const struct sLineComp *pLineComp)
  798.  * \brief  write error message, combined with string component of current src line
  799.  * \param  pMessage textual error message
  800.  * \param  Warning error is warning?
  801.  * \param  Fatal error is fatal?
  802.  * \param  pExtendError extended error explanation
  803.  * \param  pLineComp associated string component
  804.  * ------------------------------------------------------------------------ */
  805.  
  806. void WrErrorString(const char *pMessage, const char *pAdd, Boolean Warning, Boolean Fatal,
  807.                    const char *pExtendError, const struct sLineComp *pLineComp)
  808. {
  809.   String ErrStr[4];
  810.   unsigned ErrStrCount = 0, z;
  811.   char *p;
  812.   int l;
  813.   const char *pLeadIn = GNUErrors ? "" : "> > > ";
  814.   FILE *pErrFile;
  815.   Boolean ErrorsWrittenToListing = False;
  816.  
  817.   if (treat_warnings_as_errors && Warning && !Fatal)
  818.     Warning = False;
  819.  
  820.   strcpy(ErrStr[ErrStrCount], pLeadIn);
  821.   p = GetErrorPos();
  822.   if (p)
  823.   {
  824.     l = strlen(p) - 1;
  825.     if ((l >= 0) && (p[l] == ' '))
  826.       p[l] = '\0';
  827.     strmaxcat(ErrStr[ErrStrCount], p, STRINGSIZE);
  828.     free(p);
  829.   }
  830.   if (pLineComp)
  831.   {
  832.     char Num[20];
  833.  
  834.     as_snprintf(Num, sizeof(Num), ":%d", pLineComp->StartCol + 1);
  835.     strmaxcat(ErrStr[ErrStrCount], Num, STRINGSIZE);
  836.   }
  837.   if (Warning || !GNUErrors)
  838.   {
  839.     strmaxcat(ErrStr[ErrStrCount], ": ", STRINGSIZE);
  840.     strmaxcat(ErrStr[ErrStrCount], getmessage(Warning ? Num_WarnName : Num_ErrName), STRINGSIZE);
  841.   }
  842.   strmaxcat(ErrStr[ErrStrCount], pAdd, STRINGSIZE);
  843.   strmaxcat(ErrStr[ErrStrCount], ": ", STRINGSIZE);
  844.   if (Warning)
  845.     WarnCount++;
  846.   else
  847.     ErrorCount++;
  848.  
  849.   strmaxcat(ErrStr[ErrStrCount], pMessage, STRINGSIZE);
  850.   if ((ExtendErrors > 0) && pExtendError)
  851.   {
  852.     if (GNUErrors)
  853.       strmaxcat(ErrStr[ErrStrCount], " '", STRINGSIZE);
  854.     else
  855.       strcpy(ErrStr[++ErrStrCount], pLeadIn);
  856.     strmaxcat(ErrStr[ErrStrCount], pExtendError, STRINGSIZE);
  857.     if (GNUErrors)
  858.       strmaxcat(ErrStr[ErrStrCount], "'", STRINGSIZE);
  859.   }
  860.   if ((ExtendErrors > 1) || ((ExtendErrors > 0) && pLineComp))
  861.   {
  862.     strcpy(ErrStr[++ErrStrCount], "");
  863.     GenLineForMarking(ErrStr[ErrStrCount], STRINGSIZE, OneLine.p_str, pLeadIn);
  864.     if (pLineComp)
  865.     {
  866.       strcpy(ErrStr[++ErrStrCount], "");
  867.       GenLineMarker(ErrStr[ErrStrCount], STRINGSIZE, '~', pLineComp, pLeadIn);
  868.     }
  869.   }
  870.  
  871.   if (strcmp(LstName, "/dev/null") && !Fatal)
  872.   {
  873.     for (z = 0; z <= ErrStrCount; z++)
  874.       WrLstLine(ErrStr[z]);
  875.     ErrorsWrittenToListing = True;
  876.   }
  877.  
  878.   if (!ErrorFile)
  879.     OpenWithStandard(&ErrorFile, ErrorName);
  880.   pErrFile = ErrorFile ? ErrorFile : stdout;
  881.   if (strcmp(LstName, "!1") || !ListOn || !ErrorsWrittenToListing)
  882.   {
  883.     for (z = 0; z <= ErrStrCount; z++)
  884.       if (ErrorFile)
  885.         fprintf(pErrFile, "%s\n", ErrStr[z]);
  886.       else
  887.         WrConsoleLine(ErrStr[z], True);
  888.   }
  889.  
  890.   if (Fatal)
  891.     fprintf(pErrFile, "%s\n", getmessage(Num_ErrMsgIsFatal));
  892.   else if (MaxErrors && (ErrorCount >= MaxErrors))
  893.   {
  894.     fprintf(pErrFile, "%s\n", getmessage(Num_ErrMsgTooManyErrors));
  895.     Fatal = True;
  896.   }
  897.  
  898.   if (Fatal)
  899.   {
  900.     EmergencyStop();
  901.     exit(3);
  902.   }
  903. }
  904.  
  905. /*!------------------------------------------------------------------------
  906.  * \fn     WrXErrorPos(tErrorNum Num, const char *pExtendError, const struct sLineComp *pLineComp)
  907.  * \brief  write number-coded error message, combined with extended explamation and string component of current src line
  908.  * \param  Num error number
  909.  * \param  pExtendError extended error explanation
  910.  * \param  pLineComp associated string component
  911.  * ------------------------------------------------------------------------ */
  912.  
  913. void WrXErrorPos(tErrorNum Num, const char *pExtendError, const struct sLineComp *pLineComp)
  914. {
  915.   String h;
  916.   char Add[11];
  917.   const char *pErrorMsg;
  918.  
  919.   /* If issuing of a certain error or warning is disabled, a program
  920.      that expects it should trigger an error. */
  921.  
  922.   switch (Num)
  923.   {
  924.     case ErrNum_RelJumpPossible:
  925.       if (!warn_relative)
  926.         return;
  927.       break;
  928.     case ErrNum_SignExtension:
  929.       if (!warn_sign_extension)
  930.         return;
  931.       break;
  932.     default:
  933.       break;
  934.   }
  935.  
  936.   if (FindAndTakeExpectError(Num))
  937.     return;
  938.  
  939.   if (!CodeOutput && (Num == ErrNum_UnknownInstruction))
  940.     return;
  941.  
  942.   if (SuppWarns && (Num < 1000))
  943.     return;
  944.  
  945.   pErrorMsg = ErrorNum2String(Num, h, sizeof(h));
  946.  
  947.   if (((Num == ErrNum_JmpTargOnDiffPage) || (Num == ErrNum_JmpDistTooBig))
  948.    && !Repass)
  949.     JmpErrors++;
  950.  
  951.   if (NumericErrors)
  952.     as_snprintf(Add, sizeof(Add), " #%d", (int)Num);
  953.   else
  954.     *Add = '\0';
  955.   WrErrorString(pErrorMsg, Add, Num < 1000, Num >= 10000, pExtendError, pLineComp);
  956. }
  957.  
  958. /*!------------------------------------------------------------------------
  959.  * \fn     WrStrErrorPos(tErrorNum Num, const const struct sLineComp *pLineComp)
  960.  * \brief  write number-coded error message, combined with string component of current src line
  961.  * \param  Num error number
  962.  * \param  pStrComp associated string component
  963.  * ------------------------------------------------------------------------ */
  964.  
  965. void WrStrErrorPos(tErrorNum Num, const struct sStrComp *pStrComp)
  966. {
  967.   WrXErrorPos(Num, pStrComp->str.p_str, &pStrComp->Pos);
  968. }
  969.  
  970. /*!------------------------------------------------------------------------
  971.  * \fn     WrError(tErrorNum Num)
  972.  * \brief  write number-coded error message, without any explanation
  973.  * \param  Num error number
  974.  * ------------------------------------------------------------------------ */
  975.  
  976. void WrError(tErrorNum Num)
  977. {
  978.   WrXErrorPos(Num, NULL, NULL);
  979. }
  980.  
  981. /*!------------------------------------------------------------------------
  982.  * \fn     WrXError(tErrorNum Num, const char *pExtError)
  983.  * \brief  write number-coded error message with extended explanation
  984.  * \param  Num error number
  985.  * \param  pExtendError extended error explanation
  986.  * ------------------------------------------------------------------------ */
  987.  
  988. void WrXError(tErrorNum Num, const char *pExtError)
  989. {
  990.   WrXErrorPos(Num, pExtError, NULL);
  991. }
  992.  
  993. /*!------------------------------------------------------------------------
  994.  * \fn     void ChkIO(tErrorNum ErrNo)
  995.  * \brief  check for I/O error and report given error if yes
  996.  * \param  ErrNo error number to report if error occured
  997.  * ------------------------------------------------------------------------ */
  998.  
  999. void ChkIO(tErrorNum ErrNo)
  1000. {
  1001.   int io;
  1002.  
  1003.   io = errno;
  1004.   if ((io == 0) || (io == 19) || (io == 25))
  1005.     return;
  1006.  
  1007.   WrXError(ErrNo, GetErrorMsg(io));
  1008. }
  1009.  
  1010. /*!------------------------------------------------------------------------
  1011.  * \fn     ChkXIO(tErrorNum ErrNo, char *pExtError)
  1012.  * \brief  check for I/O error and report given error if yes
  1013.  * \param  ErrNo error number to report if error occured
  1014.  * \param  pExtError, file name, as plain string
  1015.  * ------------------------------------------------------------------------ */
  1016.  
  1017. void ChkXIO(tErrorNum ErrNo, char *pExtError)
  1018. {
  1019.   tStrComp TmpComp;
  1020.  
  1021.   StrCompMkTemp(&TmpComp, pExtError, 0);
  1022.   ChkStrIO(ErrNo, &TmpComp);
  1023. }
  1024.  
  1025. /*!------------------------------------------------------------------------
  1026.  * \fn     void ChkIO(tErrorNum ErrNo)
  1027.  * \brief  check for I/O error and report given error if yes
  1028.  * \param  ErrNo error number to report if error occured
  1029.  * \param  pComp, file name, as string component with position
  1030.  * ------------------------------------------------------------------------ */
  1031.  
  1032. void ChkStrIO(tErrorNum ErrNo, const struct sStrComp *pComp)
  1033. {
  1034.   int io;
  1035.   String s;
  1036.  
  1037.   io = errno;
  1038.   if ((io == 0) || (io == 19) || (io == 25))
  1039.     return;
  1040.  
  1041.   as_snprintf(s, STRINGSIZE, "%s: %s", pComp->str.p_str, GetErrorMsg(io));
  1042.   if ((pComp->Pos.StartCol >= 0) || pComp->Pos.Len)
  1043.     WrXErrorPos(ErrNo, s, &pComp->Pos);
  1044.   else
  1045.     WrXError(ErrNo, s);
  1046. }
  1047.  
  1048. /*!------------------------------------------------------------------------
  1049.  * \fn     CodeEXPECT(Word Code)
  1050.  * \brief  process EXPECT command
  1051.  * ------------------------------------------------------------------------ */
  1052.  
  1053. void CodeEXPECT(Word Code)
  1054. {
  1055.   UNUSED(Code);
  1056.  
  1057.   if (!ChkArgCnt(1, ArgCntMax));
  1058.   else if (InExpect) WrStrErrorPos(ErrNum_NoNestExpect, &OpPart);
  1059.   else
  1060.   {
  1061.     int z;
  1062.     Boolean OK;
  1063.     tErrorNum Num;
  1064.  
  1065.     for (z = 1; z <= ArgCnt; z++)
  1066.     {
  1067.       tSymbolFlags flags;
  1068.  
  1069.       Num = (tErrorNum)EvalStrIntExpressionWithFlags(&ArgStr[z], UInt16, &OK, &flags);
  1070.       if (!OK)
  1071.         continue;
  1072.       if (mFirstPassUnknownOrQuestionable(flags))
  1073.         WrStrErrorPos(ErrNum_FirstPassCalc, &ArgStr[z]);
  1074.       else if (Num)
  1075.       {
  1076.         tExpectError *pNew = (tExpectError*)calloc(1, sizeof(*pNew));
  1077.         pNew->Num = Num;
  1078.         AddExpectError(pNew);
  1079.       }
  1080.     }
  1081.     InExpect = True;
  1082.   }
  1083. }
  1084.  
  1085. /*!------------------------------------------------------------------------
  1086.  * \fn     CodeENDEXPECT(Word Code)
  1087.  * \brief  process ENDEXPECT command
  1088.  * ------------------------------------------------------------------------ */
  1089.  
  1090. void CodeENDEXPECT(Word Code)
  1091. {
  1092.   UNUSED(Code);
  1093.  
  1094.   if (!ChkArgCnt(0, 0));
  1095.   else if (!InExpect) WrStrErrorPos(ErrNum_MissingEXPECT, &OpPart);
  1096.   else
  1097.   {
  1098.     tExpectError *pCurr;
  1099.     String h;
  1100.  
  1101.     while (pExpectErrors)
  1102.     {
  1103.       pCurr = pExpectErrors;
  1104.       pExpectErrors = pCurr->pNext;
  1105.       WrXError(ErrNum_ExpectedError, ErrorNum2String(pCurr->Num, h, sizeof(h)));
  1106.       free(pCurr);
  1107.     }
  1108.     InExpect = False;
  1109.   }
  1110. }
  1111.  
  1112. /*!------------------------------------------------------------------------
  1113.  * \fn     asmerr_check_fp_dispose_result(int ret, const struct sStrComp *p_arg)
  1114.  * \brief  check the result of as_float_2...and throw associated error messages
  1115.  * \param  ret return code
  1116.  * \param  p_arg associated source argument
  1117.  * ------------------------------------------------------------------------ */
  1118.  
  1119. Boolean asmerr_check_fp_dispose_result(int ret, const struct sStrComp *p_arg)
  1120. {
  1121.   if (ret >= 0)
  1122.     return True;
  1123.   switch (ret)
  1124.   {
  1125.     case -EIO:
  1126.       WrStrErrorPos(ErrNum_UnderRange, p_arg);
  1127.       return False;
  1128.     case -EBADF:
  1129.       WrXErrorPos(ErrNum_InvArg, "raster", &p_arg->Pos);
  1130.       return False;
  1131.     case -E2BIG:
  1132.       WrStrErrorPos(ErrNum_OverRange, p_arg);
  1133.       return False;
  1134.     case -EINVAL:
  1135.       WrXErrorPos(ErrNum_InvArg, "INF/NaN", &p_arg->Pos);
  1136.       return False;
  1137.     default:
  1138.       WrStrErrorPos(ErrNum_InvArg, p_arg);
  1139.       return False;
  1140.   }
  1141. }
  1142.  
  1143. /*!------------------------------------------------------------------------
  1144.  * \fn     AsmErrPassInit(void)
  1145.  * \brief  module initialization prior to (another) pass through sources
  1146.  * ------------------------------------------------------------------------ */
  1147.  
  1148. void AsmErrPassInit(void)
  1149. {
  1150.   ErrorCount = 0;
  1151.   WarnCount = 0;
  1152.   ClearExpectErrors();
  1153.   InExpect = False;
  1154. }
  1155.  
  1156. /*!------------------------------------------------------------------------
  1157.  * \fn     AsmErrPassExit(void)
  1158.  * \brief  module checks & cleanups after a pass through sources
  1159.  * ------------------------------------------------------------------------ */
  1160.  
  1161. void AsmErrPassExit(void)
  1162. {
  1163.   if (InExpect)
  1164.     WrError(ErrNum_MissingENDEXPECT);
  1165.   ClearExpectErrors();
  1166.   InExpect = False;
  1167. }
  1168.  
  1169. static as_cmd_result_t cmd_treat_warnings_as_errors(Boolean negate, const char *p_arg)
  1170. {
  1171.   UNUSED(p_arg);
  1172.  
  1173.   treat_warnings_as_errors = !negate;
  1174.   return e_cmd_ok;
  1175. }
  1176.  
  1177. static as_cmd_result_t cmd_warn_sign_extension(Boolean negate, const char *p_arg)
  1178. {
  1179.   UNUSED(p_arg);
  1180.  
  1181.   if (negate)
  1182.     return e_cmd_err;
  1183.   warn_sign_extension = True;
  1184.   return e_cmd_ok;
  1185. }
  1186.  
  1187. static as_cmd_result_t cmd_no_warn_sign_extension(Boolean negate, const char *p_arg)
  1188. {
  1189.   UNUSED(p_arg);
  1190.  
  1191.   if (negate)
  1192.     return e_cmd_err;
  1193.   warn_sign_extension = False;
  1194.   return e_cmd_ok;
  1195. }
  1196.  
  1197. static as_cmd_result_t cmd_warn_relative(Boolean negate, const char *p_arg)
  1198. {
  1199.   UNUSED(p_arg);
  1200.  
  1201.   if (negate)
  1202.     return e_cmd_err;
  1203.   def_warn_relative = True;
  1204.   def_warn_relative_set = True;
  1205.   return e_cmd_ok;
  1206. }
  1207.  
  1208. static as_cmd_result_t cmd_no_warn_relative(Boolean negate, const char *p_arg)
  1209. {
  1210.   UNUSED(p_arg);
  1211.  
  1212.   if (negate)
  1213.     return e_cmd_err;
  1214.   def_warn_relative = False;
  1215.   def_warn_relative_set = True;
  1216.   return e_cmd_ok;
  1217. }
  1218.  
  1219. static const as_cmd_rec_t cmd_params[] =
  1220. {
  1221.   { "werror"                     , cmd_treat_warnings_as_errors },
  1222.   { "wimplicit-sign-extension"   , cmd_warn_sign_extension      },
  1223.   { "wno-implicit-sign-extension", cmd_no_warn_sign_extension   },
  1224.   { "wrelative"                  , cmd_warn_relative            },
  1225.   { "wno-relative"               , cmd_no_warn_relative         }
  1226. };
  1227.  
  1228. /*!------------------------------------------------------------------------
  1229.  * \fn     asmerr_init(void)
  1230.  * \brief  module setup
  1231.  * ------------------------------------------------------------------------ */
  1232.  
  1233. void asmerr_init(void)
  1234. {
  1235.   treat_warnings_as_errors = False;
  1236.   warn_sign_extension = True;
  1237.   def_warn_relative = def_warn_relative_set = False;
  1238.   as_cmd_register(cmd_params, as_array_size(cmd_params));
  1239. }
  1240.