home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / MultiDesktop / desk / bak / error.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-27  |  11.3 KB  |  513 lines

  1. /* MultiDesktop-Library, Fehlerbehandlung, Break, Programmende */
  2. #include <exec/alerts.h>
  3. #include "multidesktop.h"
  4.  
  5. struct GuruEntry
  6. {
  7.  ULONG  Number;
  8.  UBYTE *Text;
  9. };
  10.  
  11. struct GuruEntry GuruList[]=
  12. {
  13.  {0x00000002,"7:Bus Error"},
  14.  {0x00000003,"8:Address Error"},
  15.  {0x00000004,"9:Illegal Instruction"},
  16.  {0x00000005,"10:Divide by Zero"},
  17.  {0x00000006,"11:CHK Instruction"},
  18.  {0x00000007,"12:TRAPV Instruction"},
  19.  {0x00000008,"13:Privilege Violation"},
  20.  {0x00000009,"14:Trace"},
  21.  {0x0000000A,"15:Axxx Instruction"},
  22.  {0x0000000B,"16:Fxxx Instruction"},
  23.  {0x01000009,"Exec: Memory freed twice"},
  24.  {0x01000005,"Exec: Corrupt memory list"},
  25.  {0x0100000F,"Exec: Bad FreeMem() address"},
  26.  {0x00000000,NULL}
  27. };
  28.  
  29. struct GuruEntry GuruANList[]=
  30. {
  31.  {AN_ExecLib,     "Exec Library"},
  32.  {AN_GraphicsLib, "Graphics Library"},
  33.  {AN_Intuition,   "Intuition Library"},
  34.  {AN_LayersLib,   "Layers Library"},
  35.  {AN_MathLib,     "Math Libraries"},
  36.  {AN_DOSLib,      "DOS Library"},
  37.  {AN_RAMLib,      "Ramlib Library"},
  38.  {AN_IconLib,     "Icon Library"},
  39.  {AN_ExpansionLib,"Expansion Library"},
  40.  {AN_DiskfontLib, "Diskfont Library"},
  41.  {AN_UtilityLib,  "Utility Library"},
  42.  {AN_AudioDev,    "Audio Device"},
  43.  {AN_ConsoleDev,  "Console Device"},
  44.  {AN_GamePortDev, "Gameport Device"},
  45.  {AN_KeyboardDev, "Keyboard Device"},
  46.  {AN_TrackDiskDev,"Trackdisk Device"},
  47.  {AN_TimerDev,    "Timer Device"},
  48.  {AN_CIARsrc,     "CIA Resource"},
  49.  {AN_DiskRsrc,    "Disk Resource"},
  50.  {AN_Workbench,   "Workbench"},
  51.  {AN_GadTools,    "GadTools Library"},
  52.  {AN_Unknown,     "Unknown"},
  53.  {0x00000000,NULL}
  54. };
  55.  
  56. struct GuruEntry GuruAGList[]=
  57. {
  58.  {AG_NoMemory,  "No memory"},
  59.  {AG_MakeLib,   "Make library"},
  60.  {AG_OpenLib,   "Open library"},
  61.  {AG_OpenDev,   "Open device"},
  62.  {AG_OpenRes,   "Open resource"},
  63.  {AG_IOError,   "IO error"},
  64.  {AG_NoSignal,  "No signal"},
  65.  {AG_BadParm,   "Bad parameter"},
  66.  {AG_CloseLib,  "Close library"},
  67.  {AG_CloseDev,  "Close device"},
  68.  {AG_ProcCreate,"Process creation"},
  69.  {0x00000000,NULL}
  70. };
  71.  
  72. struct GuruEntry GuruAOList[]=
  73. {
  74.  {AO_ExecLib,     "Exec Library"},
  75.  {AO_GraphicsLib, "Graphics Library"},
  76.  {AO_Intuition,   "Intuition Library"},
  77.  {AO_LayersLib,   "Layers Library"},
  78.  {AO_MathLib,     "Math Libraries"},
  79.  {AO_DOSLib,      "DOS Library"},
  80.  {AO_RAMLib,      "Ramlib Library"},
  81.  {AO_IconLib,     "Icon Library"},
  82.  {AO_ExpansionLib,"Expansion Library"},
  83.  {AO_DiskfontLib, "Diskfont Library"},
  84.  {AO_UtilityLib,  "Utility Library"},
  85.  {AO_AudioDev,    "Audio Device"},
  86.  {AO_ConsoleDev,  "Console Device"},
  87.  {AO_GamePortDev, "Gameport Device"},
  88.  {AO_KeyboardDev, "Keyboard Device"},
  89.  {AO_TrackDiskDev,"Trackdisk Device"},
  90.  {AO_TimerDev,    "Timer Device"},
  91.  {AO_CIARsrc,     "CIA Resource"},
  92.  {AO_DiskRsrc,    "Disk Resource"},
  93.  {AO_Workbench,   "Workbench"},
  94.  {AO_GadTools,    "GadTools Library"},
  95.  {AO_Unknown,     "Unknown"},
  96.  {0000000000,NULL}
  97. };
  98.  
  99. extern struct MultiDesktopBase *MultiDesktopBase;
  100. extern struct ExecBase         *SysBase;
  101. extern APTR                     MultiDesktopTrap;
  102. extern APTR                     MultiDesktopException;
  103. struct Catalog                 *Catalog;
  104.  
  105. /* ---- Startup */
  106. void DesktopStartup(wbStartup,flags)
  107.  struct WBStartup *wbStartup;
  108.  UWORD             flags;
  109. {
  110.  UWORD                    signals;
  111.  struct MultiDesktopUser *mu;
  112.  struct Task             *task;
  113.  
  114.  task=SysBase->ThisTask;
  115.  mu=task->tc_UserData;
  116.  mu->WBStartup=wbStartup;
  117.  
  118.  if(flags & STARTUP_TRAPHANDLER)
  119.   {
  120.    mu->OldTrapHandler=task->tc_TrapCode;
  121.    task->tc_TrapCode=&MultiDesktopTrap;
  122.    task->tc_TrapData=0;
  123.   }
  124.  
  125.  if((flags & STARTUP_BREAKHANDLER_ON)||(flags & STARTUP_BREAKHANDLER_OFF))
  126.   {
  127.    signals=0;
  128.    if(flags & STARTUP_BREAKHANDLER_D) signals |= SIGBREAKF_CTRL_D;
  129.    if(flags & STARTUP_BREAKHANDLER_E) signals |= SIGBREAKF_CTRL_E;
  130.    if(flags & STARTUP_BREAKHANDLER_F) signals |= SIGBREAKF_CTRL_F;
  131.    if((flags & STARTUP_BREAKHANDLER_C)||(signals==0)) signals |= SIGBREAKF_CTRL_C;
  132.  
  133.    if(flags & STARTUP_BREAKHANDLER_ON)  mu->BreakControl=0xffff;
  134.    mu->OldExceptHandler=task->tc_ExceptCode;
  135.    task->tc_ExceptCode=&MultiDesktopException;
  136.    task->tc_ExceptData=0;
  137.    SetExcept(signals,0xffffffff);
  138.   }
  139.  
  140.  if(flags & STARTUP_ALERTHANDLER)
  141.   {
  142.    mu->AlertControl=0xffff;
  143.   }
  144. }
  145.  
  146. /* ---- Exit */
  147. void DesktopExit()
  148. {
  149.  struct MultiDesktopUser *mu;
  150.  
  151.  mu=SysBase->ThisTask->tc_UserData;
  152.  if(mu->OldTrapHandler)
  153.    SysBase->ThisTask->tc_TrapCode=mu->OldTrapHandler;
  154.  if(mu->OldExceptHandler)
  155.   {
  156.    SetExcept(0,0xffffffff);
  157.    SysBase->ThisTask->tc_ExceptCode=mu->OldExceptHandler;
  158.   }
  159. }
  160.  
  161. /* ---- User komplett terminieren */
  162. void TerminateTask(task)
  163.  struct Task *task;
  164. {
  165.  struct MultiDesktopUser *mu;
  166.  
  167.  if(task==NULL) task=SysBase->ThisTask;
  168.  mu=task->tc_UserData;
  169.  if(mu!=NULL)
  170.   {
  171.    if(mu->TermProcedure) mu->TermProcedure();
  172.    if(mu->SysTermProcedure) mu->SysTermProcedure();
  173.  
  174. /*
  175.    mu=task->tc_UserData;
  176.    if(mu)  * MultiDesktop noch offnen, weitere Schritte erforderlich *
  177.     {
  178.  
  179.     }
  180. */
  181.   }
  182. }
  183.  
  184. /* ---- Programm terminieren */
  185. void Terminate(result)
  186. {
  187.  TerminateTask(NULL);
  188.  Exit(result);
  189. }
  190.  
  191. /* ---- Fehlerprozedur festlegen */
  192. void SetSysTermProcedure(proc)
  193.  void (*proc)();
  194. {
  195.  struct MultiDesktopUser *mu;
  196.  
  197.  mu=SysBase->ThisTask->tc_UserData;
  198.  mu->SysTermProcedure=proc;
  199. }
  200.  
  201. /* ---- Fehlerprozedur ermitteln */
  202. APTR GetTermProcedure()
  203. {
  204.  struct MultiDesktopUser *mu;
  205.  
  206.  mu=SysBase->ThisTask->tc_UserData;
  207.  return(mu->TermProcedure);
  208. }
  209.  
  210. /* ---- Fehlerprozedur ermitteln */
  211. APTR GetSysTermProcedure()
  212. {
  213.  struct MultiDesktopUser *mu;
  214.  
  215.  mu=SysBase->ThisTask->tc_UserData;
  216.  return(mu->TermProcedure);
  217. }
  218.  
  219. /* ---- Anzahl der freien Task-Signale ermitteln */
  220. UBYTE AvailSignals(task)
  221.  struct Task *task;
  222. {
  223.  ULONG i;
  224.  UBYTE j;
  225.  
  226.  if(task==NULL) task=SysBase->ThisTask;
  227.  j=0;
  228.  for(i=0;i<32;i++)
  229.   {
  230.    if(!(task->tc_SigAlloc & (1L<<i))) j++;
  231.   }
  232.  return(j);
  233. }
  234.  
  235. /* ---- Anzahl der freien Task-Signale ermitteln */
  236. UBYTE AvailTraps(task)
  237.  struct Task *task;
  238. {
  239.  UWORD i;
  240.  UBYTE j;
  241.  
  242.  if(task==NULL) task=SysBase->ThisTask;
  243.  j=0;
  244.  for(i=0;i<16;i++)
  245.   {
  246.    if(!(task->tc_TrapAlloc & (1L<<i))) j++;
  247.   }
  248.  return(j);
  249. }
  250.  
  251. /* ---- Fehlercode setzen */
  252. void SetError(error)
  253.  ULONG error;
  254. {
  255.  struct MultiDesktopUser *mu;
  256.  
  257.  mu=SysBase->ThisTask->tc_UserData;
  258.  mu->LastError=error;
  259. }
  260.  
  261. /* ---- Gurucode setzen */
  262. void SetGuru(error)
  263.  ULONG error;
  264. {
  265.  struct MultiDesktopUser *mu;
  266.  
  267.  mu=SysBase->ThisTask->tc_UserData;
  268.  mu->LastGuru=error;
  269. }
  270.  
  271. /* ---- Gurucode ermitteln */
  272. ULONG GetGuru()
  273. {
  274.  struct MultiDesktopUser *mu;
  275.  ULONG                    err;
  276.  
  277.  mu=SysBase->ThisTask->tc_UserData;
  278.  err=mu->LastGuru;
  279.  mu->LastGuru=0;
  280.  return(err);
  281. }
  282.  
  283. /* ---- Fehlercode ermitteln */
  284. ULONG GetError()
  285. {
  286.  struct MultiDesktopUser *mu;
  287.  ULONG                    err;
  288.  
  289.  mu=SysBase->ThisTask->tc_UserData;
  290.  err=mu->LastError;
  291.  mu->LastError=MERR_NoError;
  292.  return(err);
  293. }
  294.  
  295. /* ---- Fehler bei zu wenig Speicherplatz */
  296. void NoMemory()
  297. {
  298.  ErrorL(0,0);
  299.  SetError(MERR_NoMemory);
  300. }
  301.  
  302. /* ---- Trap zum Abfangen von Gurus */
  303. #asm
  304.    public _MultiDesktopTrap
  305. _MultiDesktopTrap:
  306.    move.l a0,-(sp)
  307.  
  308.    move.l $4,a0             ; a0=SysBase
  309.    move.l 276(a0),a0        ; a0=SysBase->ThisTask
  310.    move.l 88(a0),a0         ; a0=SysBase->ThisTask->tc_UserData
  311.    move.l 4(sp),22(a0)      ; a0->LastGuru=GuruCode
  312.  
  313.    move.l (sp),a0           ; Rücksprungadresse ändern
  314.    addq.l #8,sp
  315.    move.l #.Guru,2(sp)
  316.    rte
  317.  
  318. DivByZero:                  ; Rücksprung zur Anwendung
  319.    move.l (sp),a0
  320.    addq.l #8,sp
  321.    rte
  322.  
  323. .Guru:                      ; Task beenden
  324.    jmp _Guru(pc)
  325.  
  326.  
  327.  ; ---- Abschnitte aus Guru-Code herausfiltern
  328.    public _GetGuruAN
  329. _GetGuruAN:
  330.    move.l 4(sp),d0
  331.    and.l #%01111111000000000000000000000000,d0
  332.    rts
  333.    public _GetGuruAG
  334. _GetGuruAG:
  335.    move.l 4(sp),d0
  336.    and.l #%00000000111111110000000000000000,d0
  337.    rts
  338.    public _GetGuruAO
  339. _GetGuruAO:
  340.    move.l 4(sp),d0
  341.    and.l #$0000ffff,d0
  342.    rts
  343. #endasm
  344.  
  345. /* ---- Fehlerprozedur festlegen */
  346. void SetTermProcedure(proc)
  347.  void (*proc)();
  348. {
  349.  struct MultiDesktopUser *mu;
  350.  
  351.  mu=SysBase->ThisTask->tc_UserData;
  352.  mu->TermProcedure=proc;
  353. }
  354.  
  355. /* ---- Guru-Nummer ausgeben und Programm terminieren */
  356. void Guru()
  357. {
  358.  BOOL                     found,recoverable;
  359.  ULONG                    guru,g;
  360.  UBYTE                    text[256];
  361.  UBYTE                    tx2[60];
  362.  struct MultiDesktopUser *mu;
  363.  long                     i;
  364.  
  365.  guru=GetGuru();
  366.  mu=SysBase->ThisTask->tc_UserData;
  367.  if(guru)
  368.   {
  369.    if((guru>=0x20)&&(guru<=0x2F))
  370.     {
  371.      sprintf(&text,FindID(Catalog,"21:Program halted!\nTrap #%ld"),guru-0x20);
  372.      ErrorRequest("20:Trap Instruction!",&text,"18:Terminate!");
  373.     }
  374.    else
  375.     {
  376.      if((guru & AT_DeadEnd)||(guru<0x20))
  377.       {
  378.        recoverable=FALSE;
  379.        sprintf(&text,FindID(Catalog,"19:Unrecoverable error in application!\nGuru #%08lx"),guru);
  380.       }
  381.      else
  382.       {
  383.        recoverable=TRUE;
  384.        sprintf(&text,FindID(Catalog,"25:Recoverable error in application!\nGuru #%08lx"),guru);
  385.        SetGuru(guru);
  386.       }
  387.  
  388.      guru &= ~AT_DeadEnd;
  389.      found=FALSE; i=0; strcpy(&tx2,"");
  390.      while(GuruList[i].Text!=NULL)
  391.       {
  392.        if(GuruList[i].Number==guru)
  393.         {
  394.          sprintf(&tx2," (%s)",FindID(Catalog,GuruList[i].Text));
  395.          strcat(&text,&tx2);
  396.          found=TRUE;
  397.         }
  398.        i++;
  399.       }
  400.  
  401.      if(found==FALSE)
  402.       {
  403.        i=0; g=GetGuruAN(guru);
  404.        while(GuruANList[i].Text!=NULL)
  405.         {
  406.          if(GuruANList[i].Number==g)
  407.           {
  408.            sprintf(&tx2,"\nSubsystem: %s",GuruANList[i].Text);
  409.            strcat(&text,&tx2);
  410.           }
  411.          i++;
  412.         }
  413.  
  414.        i=0; g=GetGuruAG(guru);
  415.        while(GuruAGList[i].Text!=NULL)
  416.         {
  417.          if(GuruAGList[i].Number==g)
  418.           {
  419.            sprintf(&tx2,"\nGeneral: %s",GuruAGList[i].Text);
  420.            strcat(&text,&tx2);
  421.           }
  422.          i++;
  423.         }
  424.  
  425.        i=0; g=GetGuruAO(guru);
  426.        while(GuruAOList[i].Text!=NULL)
  427.         {
  428.          if(GuruAOList[i].Number==g)
  429.           {
  430.            sprintf(&tx2,"\nObject: %s",GuruAOList[i].Text);
  431.            strcat(&text,&tx2);
  432.           }
  433.          i++;
  434.         }
  435.       }
  436.  
  437.      if(!recoverable)
  438.        i=ErrorRequest("17:Software error!",&text,"18:Terminate!");
  439.      else
  440.       {
  441.        i=ErrorRequest("17:Software error!",&text,"23:Continue!|Terminate!");
  442.        if(i==1) return;
  443.       }
  444.     }
  445.   }
  446.  Terminate(RETURN_FAIL);
  447. }
  448.  
  449. /* ---- Programm anhalten */
  450. void Halt()
  451. {
  452.  ErrorRequest("Halt()","22:Program haltet.","18:Terminate!");
  453.  Terminate(0);
  454. }
  455.  
  456. /* ---- Programm anhalten */
  457. void Pause()
  458. {
  459.  LONG i;
  460.  
  461.  i=ErrorRequest("Pause()","22:Program haltet.","23:Continue!|Terminate!");
  462.  if(i==0) Terminate(0);
  463. }
  464.  
  465. /* ---- Exception für CTRL-C/D/E/F */
  466. #asm
  467.    public _MultiDesktopException
  468. _MultiDesktopException:
  469.    move.l d0,-(sp)
  470.    jsr _Break(pc)
  471.    move.l (sp)+,d0
  472.    rts
  473. #endasm
  474.  
  475. /* ---- Break */
  476. void Break(signals)
  477.  ULONG signals;
  478. {
  479.  UBYTE                    str[60];
  480.  LONG                     i;
  481.  UBYTE                    chr;
  482.  struct MultiDesktopUser *mu;
  483.  
  484.  mu=SysBase->ThisTask->tc_UserData;
  485.  if(mu->BreakControl==0) return;
  486.  
  487.  if(signals & SIGBREAKF_CTRL_C) chr='C';
  488.  else if(signals & SIGBREAKF_CTRL_D) chr='D';
  489.  else if(signals & SIGBREAKF_CTRL_E) chr='E';
  490.  else if(signals & SIGBREAKF_CTRL_F) chr='F';
  491.  sprintf(&str,FindID(Catalog,"24:<Control>-<%c> detected!"),chr);
  492.  i=ErrorRequest("Break()",&str,"23:Continue!|Terminate!");
  493.  if(i==0) Terminate(0);
  494. }
  495.  
  496. /* ---- Break einschalten */
  497. void BreakOn()
  498. {
  499.  struct MultiDesktopUser *mu;
  500.  
  501.  mu=SysBase->ThisTask->tc_UserData;
  502.  mu->BreakControl=0xffff;
  503. }
  504.  
  505. /* ---- Break einschalten */
  506. void BreakOff()
  507. {
  508.  struct MultiDesktopUser *mu;
  509.  
  510.  mu=SysBase->ThisTask->tc_UserData;
  511.  mu->BreakControl=0;
  512. }
  513.