1 /*++ 2 3 Copyright (c) 2004, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 Exceptions.c 15 16 Abstract: 17 18 Exception logging routines. 19 20 --*/ 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> // for memset() 25 #include "Exceptions.h" 26 27 // 28 // Max length of a saved exception message 29 // 30 #define MAX_EXCEPTION_MSG 200 31 32 // 33 // We use this structure to track exceptions thrown. We nest deeper on 34 // TryException() calls, and come back out on CatchException() calls. 35 // We save off the first exception message for a given exception level, 36 // but we save the count of how many were thrown. 37 // 38 typedef struct { 39 int ExceptionCount; 40 char ExceptionMsg[MAX_EXCEPTION_MSG]; 41 } EXCEPTION_LOG; 42 43 static EXCEPTION_LOG ExceptionLog[MAX_EXCEPTION_NESTING + 1]; 44 static int ExceptionLevel; 45 46 // 47 // Initialize our data and structures for tracking exceptions. 48 // 49 int 50 InitExceptions ( 51 VOID 52 ) 53 { 54 ExceptionLevel = -1; 55 memset ((char *) &ExceptionLog, 0, sizeof (ExceptionLog)); 56 return 0; 57 } 58 // 59 // This function replaces the _try() exception macro. It sets the 60 // nesting level. 61 // 62 int 63 TryException ( 64 VOID 65 ) 66 { 67 // 68 // Boost our exception level if we would not go out of range 69 // 70 ExceptionLevel++; 71 if (ExceptionLevel >= MAX_EXCEPTION_NESTING) { 72 fprintf (stderr, "ERROR: Max exception nesting level exceeded\n"); 73 ExceptionLevel--; 74 return 1; 75 } 76 77 return 0; 78 } 79 // 80 // This function replaces the _catch() exception macro. It's used to decrement 81 // the nesting level and return any exeption error messages that were 82 // thrown at the current nesting level. 83 // 84 char * 85 CatchException ( 86 VOID 87 ) 88 { 89 // 90 // Return a pointer to exception message. NULL if no exceptions at this level 91 // 92 if (ExceptionLevel >= 0) { 93 ExceptionLevel--; 94 if (ExceptionLog[ExceptionLevel + 1].ExceptionMsg[0]) { 95 return ExceptionLog[ExceptionLevel + 1].ExceptionMsg; 96 } else { 97 return NULL; 98 } 99 } else { 100 fprintf (stderr, "ERROR: Invalid nesting level call to CatchException()\n"); 101 return NULL; 102 } 103 } 104 // 105 // This function can be used to test for exceptions between the TryException() 106 // and CatchException() calls in a given function. 107 // 108 int 109 ExceptionThrown ( 110 VOID 111 ) 112 { 113 return ExceptionLog[ExceptionLevel].ExceptionCount; 114 } 115 // 116 // This function replaces the _throw() exception macro. It saves off the 117 // given error message at the current exeption level nesting. 118 // 119 int 120 ThrowException ( 121 char *Msg 122 ) 123 { 124 if (ExceptionLevel < 0) { 125 // 126 // fprintf (stderr, "ERROR: Exception thrown out of scope"); 127 // Haven't yet enabled handling of exceptions, so just emit the message. 128 // 129 fprintf (stderr, Msg); 130 return 1; 131 } 132 // 133 // Only log the first 134 // 135 if (ExceptionLog[ExceptionLevel].ExceptionMsg[0] == 0) { 136 strncpy (ExceptionLog[ExceptionLevel].ExceptionMsg, Msg, MAX_EXCEPTION_MSG); 137 } 138 139 ExceptionLog[ExceptionLevel].ExceptionCount++; 140 return 0; 141 } 142