Lhogho  0.0.027
Defines | Functions | Variables
errors.h File Reference

Defines

#define FORMAT_ERR_CODE   TEXT("{ERR#%d")
#define FORMAT_ERR_POS   TEXT("@%d}")

Functions

void init_errors ()
 initializes errors
void finit_errors ()
 finalizes errors
atom_t new_error (uint_t code, atom_t data)
 creates a new error atom
atom_t new_os_error (chars_t filename)
 creates error atom for OS error
atom_t new_os_error_atom (atom_t filename)
atom_t new_parse_error (uint_t code, int position, atom_t source)
 creates error atom for parser's error
void add_error_source (atom_t error, atom_t source)
 adds new error position to an error
int get_error_position (atom_t data, chars_t *source)
 gets error position
void delete_error (atom_t a)
 deletes error atom
void dump_error (atom_t a, int level)
 dumps error atom
void clear_all_errors ()
 clears all errors

Variables

atom_t error_texts []
 Texts for error messages.
int last_os_error
 records last OS error code

Exit codes

See Errors for details

#define ERROR_INCOMPLETE_PAIR   1
#define ERROR_EMPTY_EXPRESSION   2
#define ERROR_CROWDED_EXPRESSION   3
#define ERROR_MISSING_LEFTS   4
#define ERROR_MISSING_RIGHTS   5
#define ERROR_EMPTY_TO_END   6
#define ERROR_MISSING_NAME   7
#define ERROR_DUPLICATE_INPUT   8
#define ERROR_UNKNOWN_OPTION   9
#define ERROR_CROWDED_SOURCES   10
#define ERROR_OS_ERROR   11
#define ERROR_INCOMPATIBLE_REDEFINITION   12
#define ERROR_NOT_A_NUMBER   13
#define ERROR_UNUSED_VALUE   14
#define ERROR_MISSING_VALUE   15
#define ERROR_DO_NOT_KNOW   16
#define ERROR_UNKNOWN_VAR   17
#define ERROR_BOOLEAN_EXPECTED   18
#define ERROR_NOT_AN_INTEGER   19
#define ERROR_NOT_A_LIST   20
#define ERROR_NOT_A_WORD   21
#define ERROR_INCOMPATIBLE_DATA   22
#define ERROR_TOO_BIG_NUMBER   23
#define ERROR_TOO_SMALL_NUMBER   24
#define ERROR_NOT_A_VAR   25
#define EXIT_BY_BYE   26
#define EXIT_BY_THROW_TOPLEVEL   27
#define EXIT_BY_THROW_SYSTEM   28
#define EXIT_BY_THROW_ERROR   29
#define EXIT_BY_THROW_USER_ERROR   30
#define EXIT_BY_THROW_TAG   31
#define EXIT_BY_THROW_TAG_VALUE   32
#define ERROR_NOT_A_TAG   33
#define ERROR_NOT_A_USER_FUNCTION   34
#define ERROR_VAR_HAS_NO_VALUE   35
#define ERROR_NOT_A_FUNCTION   36
#define ERROR_NOT_A_LIST_CONST   37
#define ERROR_NOT_A_WORD_CONST   38
#define ERROR_MISSING_FOR_LIMITS   39
#define ERROR_NOT_A_TYPE_NAME   40
#define ERROR_BAD_PROTOTYPE   41
#define ERROR_NOT_A_MEM   42
#define ERROR_OUT_OF_MEM   43
#define ERROR_FILE_NOT_OPENED   44
#define ERROR_NOT_BLOCK_OR_DEF   45
#define FIRST_EXIT_CODE   26
 first EXIT_ code
#define LAST_EXIT_CODE   32
 last EXIT_ code
#define LAST_ERROR_CODE   45
 last (max) error or exit code

Error fields

These macros are used to access errors. Error code is in ERRCODE(), error source is in ERRSRC(), and the error position within the source is in ERRPOS().

#define ERRCODE(x)   ((x)->unode.s[3])
#define ERRPOS(x)   ((x)->unode.a[2])
#define ERRDATA(x)   ((x)->unode.a[3])
#define IS_ERROR(x)   (ID(x)==ERROR_ID)

Define Documentation

#define ERROR_INCOMPLETE_PAIR   1
#define ERROR_EMPTY_EXPRESSION   2
#define ERROR_CROWDED_EXPRESSION   3
#define ERROR_MISSING_LEFTS   4
#define ERROR_MISSING_RIGHTS   5
#define ERROR_EMPTY_TO_END   6
#define ERROR_MISSING_NAME   7
#define ERROR_DUPLICATE_INPUT   8
#define ERROR_UNKNOWN_OPTION   9
#define ERROR_CROWDED_SOURCES   10
#define ERROR_OS_ERROR   11
#define ERROR_NOT_A_NUMBER   13
#define ERROR_UNUSED_VALUE   14
#define ERROR_MISSING_VALUE   15
#define ERROR_DO_NOT_KNOW   16
#define ERROR_UNKNOWN_VAR   17
#define ERROR_BOOLEAN_EXPECTED   18
#define ERROR_NOT_AN_INTEGER   19
#define ERROR_NOT_A_LIST   20
#define ERROR_NOT_A_WORD   21
#define ERROR_INCOMPATIBLE_DATA   22
#define ERROR_TOO_BIG_NUMBER   23
#define ERROR_TOO_SMALL_NUMBER   24
#define ERROR_NOT_A_VAR   25
#define EXIT_BY_BYE   26
#define EXIT_BY_THROW_TOPLEVEL   27
#define EXIT_BY_THROW_SYSTEM   28
#define EXIT_BY_THROW_ERROR   29
#define EXIT_BY_THROW_USER_ERROR   30
#define EXIT_BY_THROW_TAG   31
#define EXIT_BY_THROW_TAG_VALUE   32
#define ERROR_NOT_A_TAG   33
#define ERROR_NOT_A_USER_FUNCTION   34
#define ERROR_VAR_HAS_NO_VALUE   35
#define ERROR_NOT_A_FUNCTION   36
#define ERROR_NOT_A_LIST_CONST   37
#define ERROR_NOT_A_WORD_CONST   38
#define ERROR_MISSING_FOR_LIMITS   39
#define ERROR_NOT_A_TYPE_NAME   40
#define ERROR_BAD_PROTOTYPE   41
#define ERROR_NOT_A_MEM   42
#define ERROR_OUT_OF_MEM   43
#define ERROR_FILE_NOT_OPENED   44
#define ERROR_NOT_BLOCK_OR_DEF   45
#define FIRST_EXIT_CODE   26
#define LAST_EXIT_CODE   32
#define LAST_ERROR_CODE   45
#define ERRCODE (   x)    ((x)->unode.s[3])
#define ERRPOS (   x)    ((x)->unode.a[2])
#define ERRDATA (   x)    ((x)->unode.a[3])
#define IS_ERROR (   x)    (ID(x)==ERROR_ID)
#define FORMAT_ERR_CODE   TEXT("{ERR#%d")
#define FORMAT_ERR_POS   TEXT("@%d}")

Function Documentation

Initializes the table with error messages taken from TR_ERRORS.

{
  error_texts[0] = unbound;
  
  atom_t names = new_word( TR_ERRORS, UNKNOWN );
  atom_t tokens = tokenize( names, TOKENIZE_DATA );
  atom_t t = tokens; 

  // create error texts
  int i;
  for( i = 1; i<=LAST_ERROR_CODE; i++, t=CDR(t) )
    {
      #ifdef SAFEMODE
        assert( IS_NOT_EMPTY(t) ); // too few words in TR_PRIMITIVES
      #endif

      error_texts[i] = USE(CAR(t));
  }

  #ifdef SAFEMODE
    assert( IS_EMPTY(t) ); // too many words in TR_PRIMITIVES
  #endif

  DEUSE( names );
  DEUSE( tokens );
}

Frees atoms holding error texts.

{
  int i;
  for( i = 1; i<=LAST_ERROR_CODE; i++ )
    {
      DEUSE(error_texts[i]);
  }
}
atom_t new_error ( uint_t  code,
atom_t  data 
)
Parameters:
codeerror code
dataerror data
Returns:
error atom

Creates an error atom with reference count 1. The reference count of data is increased. Initializes the error position to be a list containing one element, which is the data parameter itself.

{
  //printf("-----------\n");
  //printf("new error code=%d\n",code);
  //printf("new error data="); dumpln(data);
  //printf("-----------\n");

  atom_t a = take_from_pool( &data_pool );

  #ifdef SAFEMODE
    assert( data );
  #endif //SAFEMODE

  REF(a) = 1;
  ID(a)  = ERROR_ID;
  ERRCODE(a)  = code;
  ERRPOS(a)   = new_list( USE(data), empty_list );
  ERRDATA(a)  = USE(data);

  #ifdef DEBUG_ATOM
    printf("<ATOM>  [%08x] error=[code=%d]\n",(int)a,code);
  #endif //DEBUG_ATOM

  #ifdef ADVANCED
    stats[ID(a)].allocs++;
    if( stats[ID(a)].max<(stats[ID(a)].allocs-stats[ID(a)].deallocs) )
      stats[ID(a)].max=(stats[ID(a)].allocs-stats[ID(a)].deallocs);
    stats_free--;
  #endif //ADVANCED

  #ifdef DEBUG_RUNTIME_ATOMS
  if( running_compiled_code )
    {
      outter( TEXT("<RUNTIME> new  "), -1 );
      dump_atom_address( a );
      dump_atom( a, 1 );
      outter( TEXT("\n"), -1 );
    }
  #endif
  #ifdef DEBUG_COMPILETIME_ATOMS
  if( compiling_code )
    {
      outter( TEXT("<COMPILETIME> new  "), -1 );
      dump_atom_address( a );
      dump_atom( a, 1 );
      outter( TEXT("\n"), -1 );
    }
  #endif

  if( all_errors==NULL ) all_errors = empty_list;
  all_errors = new_list( a, all_errors );

  return a;
}
atom_t new_os_error ( chars_t  filename)
Parameters:
filenamefile name associated with the error
Returns:
error atom

Creates error atom describing OS error.

{
  atom_t wrd = new_word( filename, UNKNOWN );
  new_os_error_atom( wrd );
  return new_error( ERROR_OS_ERROR, wrd );
}
{
  last_os_error = errno;
  return new_error( ERROR_OS_ERROR, filename );
}
atom_t new_parse_error ( uint_t  code,
int  position,
atom_t  source 
)
Parameters:
codeerror code
positioncharacter position within the source
source(sub)word containing the source
Returns:
error atom

Creates error atom describing an error generated by the parser.

{
  atom_t errsrc = new_subword( source, STRING(source)+position, 1 );
  atom_t error = new_error( code, unbound );
  CAR(ERRPOS(error)) = errsrc;
  return error;
}
void add_error_source ( atom_t  error,
atom_t  source 
)
Parameters:
errorerror to which new position will be added
sourceerror source

Adds a new error position to an already existing error atom. The error position is simply an atom which may have been extracted from the actual source. The new error position is inserted in the first place of the list of error positions.

{
  //printf("register error pos>>>---------------\n");
  //printf("register error src>>>"); dumpln(source);
  //printf("register error err>>>"); dumpln(error);
  //printf("register error pos>>>---------------\n");
  //printf("errpos old ref=%d\n",REF(ERRPOS(error)));
  ERRPOS(error) = new_list( USE(source), ERRPOS(error) );
  //printf("errpos new ref=%d\n",REF(ERRPOS(error)));
}
int get_error_position ( atom_t  data,
chars_t source 
)
Parameters:
datadata to search for
sourcesource where the data is found
Returns:
position of data within found source

Tries to identify the position of the first (sub)word in the data in the original source. This function returns the character position and the source. If the source cannot be identified, then return -1 and set source to NULL.

{
  // dig in a list to find the first (sub)word
  while( IS_LIST(data) & IS_NOT_EMPTY(data) ) data = CAR(data);

  // if it is a word then return we have found something
  if( IS_WORD(data) )
    {
      *source = STRING(data);
      return 0;
    }

  // if it is a subword then return we have found something
  if( IS_SUBWORD(data) )
    {
      *source = STRING(WORD(data));
      return STRING(data)-STRING(WORD(data));
    }

  // no, could not find the error position
  *source = NULL;
  return -1;
}
Parameters:
aatom to delete

Deletes error atom by returning it back to the data pool. The source atom is dereferenced.

{
  //printf("****** DELETING ERROR ****** [%x]\n",(int)a);
  DEUSE( ERRPOS(a) );
  DEUSE( ERRDATA(a) );
  return_to_pool( &data_pool, a );
}
void dump_error ( atom_t  a,
int  level 
)
Parameters:
aatom to dump
leveldump level

Dumps error atom through the current outter function.

{
  #define DUMP_BUF_SIZE 128
  char_t buf[DUMP_BUF_SIZE];
  int n;

  //printf("<<err ref=%d>> ",REF(a));
  //printf("temporary dump of an error\n");
  //printf(">>>>>>error ref  = %d\n",REF(a));
  //printf(">>>>>>error code = %d\n",ERRCODE(a));
  //printf(">>>>>>error posn = "); dumpln(ERRPOS(a));
  //printf(">>>>>>error data = "); dumpln(ERRDATA(a));
  //return;

  int errpos = -1;
  int errpos2 = -1;
  int errpos3 = -1;
  chars_t errsrc = NULL;
  chars_t errsrc2 = NULL;
  chars_t errsrc3 = NULL;
  atom_t p;
  //printf("errpos="); dump_atom(ERRPOS(a),1); printf("\n------------\n");
  for( p=ERRPOS(a); IS_NOT_EMPTY(p); p=CDR(p) )
    {
      //printf("ERRPOS=");dumpln(CAR(p));
      chars_t src;
      int pos = get_error_position( CAR(p), &src );
      if( pos>-1 )
   {
     errpos3 = errpos2;
     errsrc3 = errsrc2;
     errpos2 = errpos;
     errsrc2 = errsrc;
     errpos = pos;
     errsrc = src;
   }
      //printf("pos=%d source=",pos); dumpln(CAR(p));
    }

  if( ERRCODE(a)==EXIT_BY_THROW_USER_ERROR )
    {
      errpos = errpos3;
      errsrc = errsrc3;
    }

  // print error code
  n = SPRINTF( buf, DUMP_BUF_SIZE, FORMAT_ERR_CODE, ERRCODE(a) );
  outter( buf, n );

  // print error position
  n = SPRINTF( buf, DUMP_BUF_SIZE, FORMAT_ERR_POS, errpos );
  outter( buf, n );

  // print error message
  if( ERRCODE(a)==EXIT_BY_THROW_USER_ERROR )
    {
      outter( TEXT(" - "), 3 );
      dump( ERRDATA(a) );
    }
  else
    {
      #ifdef SAFEMODE
        assert( ERRCODE(a)>0 );
        assert( ERRCODE(a)<=LAST_ERROR_CODE );
      #endif
      outter( TEXT(" - "), 3 );
      dump( error_texts[ERRCODE(a)] );
    }

  if( ERRCODE(a)==ERROR_OS_ERROR )
    {
      chars_t msg = UNFILENAME(strerror(last_os_error));
      outter( TEXT(": "), 2 );
      outter( msg, -1 );
      DEALLOC( msg );
    }
  outter( TEXT("\n"), -1 );

  // print error source
  dump_neighbourhood( errsrc, errpos );
}

Clears all errors recorder in all_errors except for the one stored in last_error

{
  atom_t err = all_errors;
  if( err==NULL ) return;

  //printf("===INSIDE CLEAR_ALL_ERRORS===\n");
  //printf("===EXCEPTION(%d):  ",REF(last_error)); dumpln(last_error);
  //printf("===ALL ERRORS (BEFORE): "); dumpln(all_errors);

  //printf("===START ERROR SCANNING===\n");
  while( IS_NOT_EMPTY(err) )
    {
      //printf("===ERROR: [%x]\n",CAR(err));
      if( CAR(err)!=last_error ) REF(CAR(err)) = 1;
      err = CDR(err);
    }
  //printf("===END ERROR SCANNING===\n");

  USE( last_error );
  //printf("AEREF=%d !!!!!!!!!!!!!!!!\n",REF(all_errors));
  DEUSE( all_errors );
  //printf("AEREF=%d !!!!!!!!!!!!!!!!\n",REF(all_errors));
  DEUSE( last_error );

  all_errors = empty_list;
  //printf("===END OF CLEAR_ALL_ERRORS===\n\n");
}

Variable Documentation


[ HOME | INDEX | ATOMS | VARS | REFERENCE ]
Lhogho Developer's Documentation
Tue Feb 7 2012