Home | History | Annotate | Download | only in ProcessDsc
      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